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