HDU 1269 迷宫城堡(Tarjan算法)
Tarjan算法模版求强连通分量。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 using namespace std; 6 #define N 10000 7 #define M 100000 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]; 14 int in[N+1]; 15 void CL() 16 { 17 t = 0; 18 t = scnt = top = 0; 19 memset(first,-1,sizeof(first)); 20 memset(DFN,0,sizeof(DFN)); 21 } 22 void add(int u,int v) 23 { 24 edge[t].u = u; 25 edge[t].v = v; 26 edge[t].next = first[u]; 27 first[u] = t ++; 28 } 29 void Tarjan(int u) 30 { 31 int v,i; 32 DFN[u] = Low[u] = ++ t; 33 in[u] = 1; 34 stack[top++] = u; 35 for(i = first[u];i != -1;i = edge[i].next) 36 { 37 v = edge[i].v; 38 if(!DFN[v]) 39 { 40 Tarjan(v); 41 if(Low[u] > Low[v]) 42 { 43 Low[u] = Low[v]; 44 } 45 } 46 else if(in[v] && Low[u] > DFN[v]) 47 { 48 Low[u] = DFN[v]; 49 } 50 } 51 if(DFN[u] == Low[u]) 52 { 53 scnt ++; 54 do 55 { 56 v = stack[--top]; 57 in[v] = 0; 58 Belong[v] = scnt; 59 }while(u != v); 60 } 61 } 62 int main() 63 { 64 int n,m,sv,ev,i; 65 while(scanf("%d%d",&n,&m)!=EOF) 66 { 67 if(n == 0&&m == 0) 68 break; 69 CL(); 70 for(i = 1;i <= m;i ++) 71 { 72 scanf("%d%d",&sv,&ev); 73 add(sv,ev); 74 } 75 t = 0; 76 for(i = 1;i <= n;i ++) 77 { 78 if(!DFN[i]) 79 { 80 Tarjan(i); 81 } 82 } 83 if(scnt == 1) 84 printf("Yes\n"); 85 else 86 printf("No\n"); 87 } 88 return 0; 89 }