第一道强连通题。。。以前貌似用并查集做过。。。
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 100000
int tot;
struct Node
{
int to;
int next;
} edge[maxn];
int head[maxn];
int dfn[maxn];
int low[maxn];
int vis[maxn];
int st[maxn];
int ans,top,kas;
void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void tarjan(int u)
{
vis[u]=1;
dfn[u]=low[u]=++kas;
st[++top]=u;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
if(!dfn[edge[i].to])//是否被访问过
{
tarjan(edge[i].to);
low[u]=min(low[u],low[edge[i].to]);
}
else if(vis[edge[i].to])//访问过了,并且还在栈里(访问过了,但不在栈里,说明这个点已经找到了自己的归宿)
{
low[u]=min(low[u],dfn[edge[i].to]);
}
}
if(low[u]==dfn[u])
{
ans++;
while(1)
{
if(st[top]==u)
{
vis[st[top]]=0;//不要忘记取消
top--;
break;
}
else
{
vis[st[top]]=0;
top--;
}
}
}
}
int main()
{
int n,m,a,b;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
tot=0;
ans=0;
top=0;
kas=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
for(int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
for(int i=1; i<=n; i++)//比如两个强连通分量由一条边相连在一起,,,所以需要都扫一遍
{
if(!dfn[i])
{
tarjan(i);
}
}
if(ans==1)
{
puts("Yes");
}
else
puts("No");
}
return 0;
}