//这道题WA的惨烈,又跪在n,m同时为0输入结束这个点上 //以后用n+m或者n||m,不要再用n&&m判了 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdlib> #include<vector> using namespace std; typedef long long ll; const int MAXN=100010; struct edge { int next,to; }E[MAXN]; int head[MAXN],Ecou; //Ecou:边下标 int Stack[MAXN],top; //top:栈顶 int Belong[MAXN],Bcnt; //Bcnt:强连通分量个数 int Index; //Index:时间戳 int DFN[MAXN],LOW[MAXN]; bool inStack[MAXN]; void add_edge(int u,int v) { E[Ecou].to=v; E[Ecou].next=head[u]; head[u]=Ecou++; } void Tarjan(int u) { int v; LOW[u]=DFN[u]=++Index; Stack[top++]=u; inStack[u]=true; for(int i=head[u];i!=-1;i=E[i].next) { v=E[i].to; if(!DFN[v]) { Tarjan(v); if(LOW[u]>LOW[v]) LOW[u]=LOW[v]; } else if(inStack[v]&&LOW[u]>DFN[v]) LOW[u]=DFN[v]; } if(LOW[u]==DFN[u]) { ++Bcnt; do { v=Stack[--top]; inStack[v]=false; Belong[v]=Bcnt; }while(v!=u); } } void getSCC(int n) { for(int i=1;i<=n;i++) if(!DFN[i]) Tarjan(i); } void init(int n) { Ecou=Index=Bcnt=top=0; for(int i=1;i<=n;i++) { head[i]=-1; DFN[i]=LOW[i]=Belong[i]=0; inStack[i]=0; } } int main() { int n,m,u,v,i; while(scanf("%d %d",&n,&m)&&n+m) { init(n); while(m--) { scanf("%d %d",&u,&v); add_edge(u,v); } getSCC(n); for(i=2;i<=n;i++) if(Belong[i]!=Belong[i-1]) break; if(i>n) printf("Yes\n"); else printf("No\n"); } return 0; }
原文:http://www.cnblogs.com/atmacmer/p/5196897.html