Legal or Not 原题链接
题目大致意思是,判断关系是否合法,列如:一个师傅可以有很多师徒,一个师徒也可能有很多师傅,A是B的徒弟,B是A的徒弟,是违法
解析:
根据题目意思要判别是否出现a是b的师傅(非严格意义的师傅,列入a的徒弟是b的师傅,a也是b的师傅),b是a的师傅,如果出现就输出No反之就是Yes。
对题目加以分析不难看出所谓的a是b的师傅b是a的师傅就是看有无闭环,拓扑排序刚好由此功能
#include "bits/stdc++.h"
using namespace std;
#define int long long
const int mxn=110;
int head[mxn],ant,m,n,a,b,in[mxn];//存放每个节点的入度
struct g{
int to,nxt;
}edge[mxn];//存放边;
void add(int u,int v){ //u——>v
edge[ant].to=v;
edge[ant].nxt=head[u];
head[u]=ant++;
in[v]++;//更新入度
}
int que[mxn];
bool topsort();//拓扑排序判断有无闭环
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
while(cin>>n>>m&&n){
memset(head ,-1,sizeof head);
memset(in,0,sizeof in);
ant=0;
for(int i=1;i<=m;i++)
cin>>a>>b,add(a,b);
cout<<(topsort()?"YES":"NO")<<'\n';
}
return 0;
}
bool topsort(){
int tt=0,hh=0;
for(int i=0;i<n;i++) if(!in[i]) que[++tt]=i;
while(hh<tt){
int x=head[que[++hh]];
for(x;~x;x=edge[x].nxt){
int nx=edge[x].to;
in[nx]--;
if(!in[nx]) que[++tt]=nx;
}
}
return hh==n;
}