本来以为这题能用并查集做的,但一想不对
例如A-> B,A->C如果用并查集的话B与C就不能连了,但实际B可以是C的徒弟,所以这题是考拓扑排序。
#include<stdio.h>
#include<string.h>
int d[],map[][],vis[];
int main()
{
int i,j,k,f,n,m,u,v;
while(~scanf("%d%d",&n,&m))
{
if(n==) break;
memset(d,,sizeof(d));
memset(map,,sizeof(map));
memset(vis,,sizeof(vis));
for(i=; i<=m; i++)
{
scanf("%d%d",&u,&v);
if(!map[u][v])//这里很重要,因为可能有输入重复的点
{
map[u][v]=;
d[v]++;
}
}
for(i=; i<n; i++)
{
f=;
for(j=; j<n; j++)
{
if(d[j]==&&vis[j]==)//用于处理存在好几个入度为0的节点
{
vis[j]=;
for(k=; k<n; k++)
if(map[j][k])
d[k]--;
f=;
break;//找到一个入度为0的就结束
}
}
if(f==)//如果节点未输出完,而图中就没有了入度为0的节点,则说明有环,不合法。
break;
}
if(f==)
printf("NO\n");
else
printf("YES\n");
}
}