HDU 3342 Legal or Not 拓扑排序

http://acm.hdu.edu.cn/showproblem.php?pid=3342

题意:

  输入N,M代表有0~N-1的点,M组数据 ,输入的每组数据代表 a指向b ,然后用这M组数据构成一个有向图,判断这个

图有没有环,有就NO,没有就YES。

 

坑爹:

  用了vector开的数组,如果中途发现  k == -1 的时候,有很多节点没有删除,所以要在每一次拓扑完之后将map数组

清空。

 

解法:

  利用拓扑排序,每次找入度为0的点,然后把与他相连的边清除掉,并且将与他相连的点的入度减1。

 

View Code
 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 
 5 const int maxn = 500 + 10;
 6 int IN[maxn];
 7 int used[maxn];
 8 vector <int> map[maxn];
 9 int N;
10 
11 int find_zero()
12 {
13     int i;
14     for(i=0; i<N; i++)
15     {
16         if(!used[i] && IN[i]==0)
17         {
18             return i;
19         }
20     }
21     return -1;
22 }
23 
24 void cut(int k)
25 {
26     int i;
27     for(i=0; i<map[k].size(); i++)
28     {
29         IN[map[k][i]]--;
30     }
31     map[k].clear();
32 }
33 
34 void topology()
35 {
36     int i;
37     int k=0;
38     int flag=0;
39     for(i=0; i<N; i++)
40     {
41         k=find_zero();
42         if(k==-1)
43         {
44             flag=1;
45             cout<<"NO"<<endl;
46             break;
47         }
48         cut(k);
49         used[k]=1;
50     }
51     if(!flag)
52     {
53         cout<<"YES"<<endl;
54     }
55 }
56 
57 int main()
58 {
59     int M;
60     while(cin>>N>>M,N)
61     {
62         memset(used,0,sizeof(used));
63         memset(IN,0,sizeof(IN));
64         int i;
65         
66         for(i=0; i<M; i++)
67         {
68             int a;
69             int b;
70             cin>>a>>b; 
71             map[a].push_back(b);
72             IN[b]++;
73         }
74         topology();
75         for(i=0; i<N; i++)
76         {
77             map[i].clear();
78         }
79     }
80     return 0;
81 }

 

posted @ 2012-09-08 11:05  pc....  阅读(161)  评论(0)    收藏  举报