题意:
ACM-DIY是一个庞大的QQ群,许多优秀的电脑爱好者聚集在一起。它就像一个大家庭一样和谐。每天,许多像HH,AC,ZT,lcc,BF,Qinz等“圣牛”在线聊天交流他们的想法。当有人有疑问时,许多热情的牛如迷失会来帮忙。然后那个被帮助的人会叫迷失的“主人”,而迷失会有一个不错的“徒弟”。过去和现在,有许多“主人和指导者”。但是接下来会出现问题:主人太多,指环太多,我们怎么知道这是否合法?
我们都知道一个主人可以有很多指导,而一个指导者也可以有很多主人,这是合法的。尽管如此,有些奶牛并不那么诚实,他们持有非法关系。以HH和3x为瞬间,HH是3xian的主人,同时3xian是HH的主人,这是非常非法的!为了避免这种情况,请帮助我们判断他们的关系是否合法。
请注意,“主人与叔叔”关系是及物动词。这意味着如果A是B的主人,B是C的主人,那么A是C的主人。
思路:
其实这是一个简单的有向图判环问题,这类题通常采用拓扑排序解决。
下面放上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=105;
int n,m;
int tol;
int indeg[maxn];//入度
struct node
{
int u,v;
}edge[maxn*maxn];//存图
void addedge(int u,int v)//加边,统计终点的入度
{
edge[tol].u=u;
edge[tol++].v=v;
indeg[v]++;
}
int topo()
{
queue <int> q;
int cnt=0;
for(int i=0;i<n;i++)//入度为0的点入列
{
if(indeg[i]==0)
q.push(i);
}
while(!q.empty())
{
int now=q.front();
q.pop();
cnt++;//计数
for(int i=0;i<tol;i++)
{
if(edge[i].u==now)
{
indeg[edge[i].v]--;//删边
if(indeg[edge[i].v]==0)//点入度为0,入队
q.push(edge[i].v);
}
}
}
if(cnt<n)//不存在
return 0;
else
return 1;
}
int main()
{
int begin,end;
while(~scanf("%d%d",&n,&m)&&(n+m))
{
memset(indeg,0,sizeof(indeg));
tol=0;
while(m--)
{
scanf("%d%d",&begin,&end);
addedge(begin,end);
}
if(topo())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}