很水的TARJAN求强联通图的问题。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;
const int N=10010;
const int M=100010;
int head[N],dfn[N],low[N],stack[N],st;
struct Edge{int u,v;int nxt;
}edge[M];
int tot,n,m,nTime,btn;
int vis[N];
bool instack[N];
void addedge(int u,int v){edge[tot].u=u;edge[tot].v=v;edge[tot].nxt=head[u];head[u]=tot++;
}void tarjan(int u,int ufa){dfn[u]=low[u]=++nTime;stack[++st]=u;instack[u]=true;for(int e=head[u];e!=-1;e=edge[e].nxt){int v=edge[e].v;// cout<<v<<endl;if(dfn[v]==-1){tarjan(v,u);low[u]=min(low[u],low[v]);}else if(instack[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){int v; btn++;do{v=stack[st--];vis[v]=btn;}while(u!=v);}
}int main(){int u,v;while(scanf("%d%d",&n,&m),n||m){memset(head,-1,sizeof(int)*(n+5));memset(dfn,-1,sizeof(int)*(n+5));memset(low,-1,sizeof(int)*(n+5));memset(vis,0,sizeof(int)*(n+5));memset(instack,false,sizeof(bool)*(n+5));tot=0;nTime=0;st=0;btn=0;for(int i=1;i<=m;i++){scanf("%d%d",&u,&v);addedge(u,v);}tarjan(1,0);bool flag=true;for(int i=2;i<=n;i++)if(vis[i]!=vis[1]){flag=false;break;}if(flag){puts("Yes");}else puts("No");}return 0;
}