很水的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;
}