USACO 4.3 Street Race(DFS)

本来想用floyd的,利用p[i][j] < INF&&p[j][i] < INF 来判断的,提交发现在前边或者后边的跑道存在环的时候,这样做是错的。。。我改了一下,直接暴力。。。

  1 /*
  2 ID:cuizhe
  3 LANG: C++
  4 TASK: race3
  5 */
  6 #include <cstdio>
  7 #include <cmath>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <map>
 11 #include <queue>
 12 #include <algorithm>
 13 using namespace std;
 14 #define INF 100000
 15 int p[101][101];
 16 int o[101];
 17 int flag[101];
 18 int n;
 19 int dfs(int x)
 20 {
 21     int i;
 22     if(x == n) return 1;
 23     for(i = 0;i <= n;i ++)
 24     {
 25         if(p[x][i] == 1&&!o[i])
 26         {
 27             o[i] = 1;
 28             if(dfs(i))
 29             return 1;
 30             o[i] = 0;
 31         }
 32     }
 33     return 0;
 34 }
 35 void dfs1(int x,int key)
 36 {
 37     int i;
 38     if(x == key) return;
 39     for(i = 0;i <= n;i ++)
 40     {
 41         if(p[x][i] == 1&&!o[i])
 42         {
 43             o[i] = 1;
 44             dfs1(i,key);
 45         }
 46     }
 47     return ;
 48 }
 49 int dfs2(int x,int key)
 50 {
 51     int i;
 52     if(x == key) return 0;
 53     for(i = 0;i <= n;i ++)
 54     {
 55         if(p[x][i] == 1&&!o[i])
 56         {
 57             o[i] = 2;
 58             if(dfs2(i,key))
 59             return 1;
 60         }
 61         else if(p[x][i] == 1&&o[i] == 1)
 62         {
 63             return 1;
 64         }
 65     }
 66     return 0;
 67 }
 68 int main()
 69 {
 70     int i,j,num,ans = 0;
 71     freopen("race3.in","r",stdin);
 72     freopen("race3.out","w",stdout);
 73     for(i = 0;i <= 50;i ++)
 74     {
 75         for(j = 0;j <= 50;j ++)
 76         p[i][j] = INF;
 77         p[i][i] = 0;
 78     }
 79     for(i = 0;;i ++)
 80     {
 81         scanf("%d",&num);
 82         if(num == -1) break;
 83         if(num == -2) continue;
 84         p[i][num] = 1;
 85         for(;;)
 86         {
 87             scanf("%d",&num);
 88             if(num == -2) break;
 89             p[i][num] = 1;
 90         }
 91     }
 92     n = i-1;
 93     for(i = 1;i < n;i ++)
 94     {
 95         memset(o,0,sizeof(o));
 96         o[i] = 1;
 97         if(!dfs(0))
 98         {
 99             flag[i] = 1;
100             ans ++;
101         }
102         o[i] = 0;
103     }
104     printf("%d",ans);
105     for(i = 1;i < n;i ++)
106     {
107         if(flag[i]) printf(" %d",i);
108     }
109     printf("\n");
110     ans = 0;
111     for(i = 1;i < n;i ++)
112     {
113         if(flag[i])
114         {
115             memset(o,0,sizeof(o));
116             o[0] = 1;
117             dfs1(0,i);
118             o[i] = 2;
119             if(dfs2(i,n))
120             continue;
121             else
122             {
123                 flag[i] = 2;
124                 ans ++;
125             }
126         }
127     }
128     printf("%d",ans);
129     for(i = 1;i < n;i ++)
130     {
131         if(flag[i] == 2) printf(" %d",i);
132     }
133     printf("\n");
134     return 0;
135 }

 

转载于:https://www.cnblogs.com/naix-x/archive/2013/03/27/2984213.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值