这道题目就是求强连通分量。。。
AC代码:
#include<iostream>v
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10005;
struct Edge
{
int key,next;
}edge[100000];
int pre[maxn],cnt,n,m,dfsNum,sccNum,top;
int stack[maxn],instack[maxn],dfsnum[maxn],low[maxn];
void addedge(int x,int y)
{
edge[cnt].key = y;
edge[cnt].next = pre[x];
pre[x] = cnt++;
}
void Tarjan(int cur)
{
dfsnum[cur] = ++dfsNum;
low[cur] = dfsnum[cur];
stack[top++] = cur;
instack[cur] = 1;
for(int i = pre[cur]; i != -1; i = edge[i].next)
{
int v = edge[i].key;
if(dfsnum[v] == 0) // 子树中还有边未遍历
{
Tarjan(v);
if(low[cur] > low[v])
low[cur] = low[v];
}
else if(instack[v]) //表示有父子关系,存在回边
{
if(low[cur] > dfsnum[v])
low[cur] = dfsnum[v];
}
}
if(low[cur] == dfsnum[cur]) //该点是强连通分量的根节点
{
while(top != 0 && stack[top-1] != cur)
{
instack[stack[top-1]] = 0;
top--;
}
sccNum++;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF && m + n)
{
memset(pre,-1,sizeof(pre));
memset(instack,0,sizeof(instack));
cnt = top = sccNum = dfsNum = 0;
for(int i = 1; i <= m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
addedge(a,b);
}
for(int i = 1; i <= n; i++)
if(dfsnum[i] == 0)
Tarjan(i);
if(sccNum == 1)
printf("Yes\n");
else printf("No\n");
}
return 0;
}