强连通分量模板
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<stack> #include<vector> using namespace std; const int maxn=10005; vector<int> G[maxn]; int N,M,ans; bool inq[maxn]; //是否在栈内 int nid,dfn[maxn],low[maxn]; //dfn相当于重新编号,low能搜到的最小编号 stack<int> KK; //栈 void init() //初始化 { ans=nid=0; for(int i=0;i<=N;i++) { inq[i]=false; dfn[i]=low[i]=0; } while(!KK.empty()) KK.pop(); } void Tarjan(int u) { dfn[u]=low[u]=++nid; //编号 KK.push(u); inq[u]=true; //丢进栈里 int Size=G[u].size(); for(int i=0;i<Size;i++) { int v=G[u][i]; if(!dfn[v]) //没有访问过 { Tarjan(v); low[u]=min(low[u],low[v]); } else if(inq[v]) low[u]=min(low[u],dfn[v]); //访问过在栈里 } if(dfn[u]==low[u])//相等说明这是一个连通分量 { ans++; int v; do { v=KK.top(); KK.pop(); inq[v]=false; }while(v!=u); } } int main() { while(scanf("%d%d",&N,&M)!=EOF) { if(!N&&!M) break; for(int i=0;i<=N;i++) G[i].clear(); int u,v; while(M--) { scanf("%d%d",&u,&v); G[u].push_back(v); } init(); for(int i=1;i<=N;i++) if(!dfn[i]) Tarjan(i); if(ans<=1) printf("Yes\n"); else printf("No\n"); } return 0; }