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。

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 }