POJ 2186 Popular Cows(Tarjan)
看着DISCUSS各种改。。Tarjan每个点属于那个连通块,枚举度数,统计出度。如果出度为0的有一个,这个块的个数就是结果。出度为0的大于1,则没有。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 using namespace std; 6 #define N 10001 7 #define M 50001 8 struct node 9 { 10 int u,v,next; 11 } edge[M+10]; 12 int t,top,scnt; 13 int DFN[N+1],Low[N+1],Belong[N+1],stack[N+1],first[N+1],count[N+1]; 14 int in[N+1],flag[N+1]; 15 int quex[M+1],quey[M+1]; 16 void CL() 17 { 18 t = 0; 19 t = scnt = top = 0; 20 memset(first,-1,sizeof(first)); 21 memset(DFN,0,sizeof(DFN)); 22 memset(flag,0,sizeof(flag)); 23 memset(count,0,sizeof(count)); 24 } 25 void add(int u,int v) 26 { 27 edge[t].u = u; 28 edge[t].v = v; 29 edge[t].next = first[u]; 30 first[u] = t ++; 31 } 32 void Tarjan(int u) 33 { 34 int v,i; 35 DFN[u] = Low[u] = ++ t; 36 in[u] = 1; 37 stack[top++] = u; 38 for(i = first[u]; i != -1; i = edge[i].next) 39 { 40 v = edge[i].v; 41 if(!DFN[v]) 42 { 43 Tarjan(v); 44 if(Low[u] > Low[v]) 45 { 46 Low[u] = Low[v]; 47 } 48 } 49 else if(in[v] && Low[u] > DFN[v]) 50 { 51 Low[u] = DFN[v]; 52 } 53 } 54 if(DFN[u] == Low[u]) 55 { 56 scnt ++; 57 do 58 { 59 v = stack[--top]; 60 in[v] = 0; 61 Belong[v] = scnt; 62 count[scnt] ++; 63 } 64 while(u != v); 65 } 66 } 67 int main() 68 { 69 int n,m,sv,ev,num,key,i; 70 while(scanf("%d%d",&n,&m)!=EOF) 71 { 72 CL(); 73 for(i = 1; i <= m; i ++) 74 { 75 scanf("%d%d",&sv,&ev); 76 quex[i] = sv; 77 quey[i] = ev; 78 add(sv,ev); 79 } 80 t = 0; 81 for(i = 1; i <= n; i ++) 82 { 83 if(!DFN[i]) 84 Tarjan(i); 85 } 86 for(i = 1; i <= m; i ++) 87 { 88 if(Belong[quex[i]] != Belong[quey[i]]) 89 { 90 flag[Belong[quex[i]]] ++; 91 } 92 } 93 num = 0; 94 for(i = 1; i <= scnt; i ++) 95 { 96 if(flag[i] == 0) 97 { 98 num ++; 99 key = i; 100 } 101 } 102 if(num == 1) 103 printf("%d\n",count[key]); 104 else 105 printf("0\n"); 106 } 107 return 0; 108 }