题目大意
给你一个 n(n<=10000) 个节点的图,让你判断这个图是否是一个强连通图
做法分析
直接用 tarjan 算法求强连通分量即可
参考代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <stack> 5 6 using namespace std; 7 8 const int N=10006; 9 10 struct Edge 11 { 12 int u, next; 13 Edge(){} 14 Edge(int a, int b) 15 { 16 u=a, next=b; 17 } 18 }edge[100006]; 19 int head[N], tot; 20 21 void add_edge(int st, int en) 22 { 23 edge[tot]=Edge(en, head[st]); 24 head[st]=tot++; 25 } 26 27 int dfn[N], low[N], T, ind; 28 bool vs[N]; 29 stack <int> S; 30 31 void tarjan(int u) 32 { 33 S.push(u), vs[u]=1; 34 low[u]=dfn[u]=T++; 35 for(int e=head[u]; e!=-1; e=edge[e].next) 36 { 37 int v=edge[e].u; 38 if(dfn[v]==-1) 39 { 40 tarjan(v); 41 low[u]=min(low[u], low[v]); 42 } 43 else if(vs[v] && dfn[v]<low[u]) low[u]=dfn[v]; 44 } 45 if(dfn[u]==low[u]) 46 { 47 for(int v; 1; ) 48 { 49 v=S.top(); 50 S.pop(), vs[v]=false; 51 if(v==u) break; 52 } 53 ind++; 54 } 55 } 56 57 int main() 58 { 59 int n, m; 60 while(scanf("%d%d", &n, &m), n!=0 || m!=0) 61 { 62 memset(head, -1, sizeof head); 63 tot=0; 64 for(int i=0, a, b; i<m; i++) 65 { 66 scanf("%d%d", &a, &b); 67 add_edge(a, b); 68 } 69 memset(dfn, -1, sizeof dfn); 70 memset(vs, 0, sizeof vs); 71 while(!S.empty()) S.pop(); 72 T=ind=0; 73 for(int i=1; i<=n; i++) if(dfn[i]==-1) tarjan(i); 74 if(ind==1) printf("Yes\n"); else printf("No\n"); 75 } 76 return 0; 77 }