题目大意:有n个人,m组关系(题目没有说没有重边,若用邻接矩阵,会被坑惨),<a,b>表示a是b的主人,若存在关系<a,b>,<b,c>,则<a,c>,也就是说a是b的主人,b是c的主人,那么a也是c的主人,这种关系是合法的,则输出YES,若a是b的主人,b是c的主人,c确是a的主人,那么这种关系不合法,则输出NO;
思路:这里主要判断是否能进行拓扑排序,若存在环,则不能进行拓扑排序,我们进行拓扑排序,会将每一个入度为0的点压入队列,若弹出点的个数刚好为n个,则说明能进行拓扑排序,反之若小于n,表明成环
1.邻接矩阵
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 1<<31-1
#define maxn 111
using namespace std;
int in[maxn],n,m,mapp[maxn][maxn];
int tuopu()
{
int cnt = 0;
queue<int>q;
for(int i=0;i<n;i++) if(!in[i]) q.push(i);
while(!q.empty())
{
int a = q.front();
q.pop();
cnt++;
for(int i=0;i<n;i++)
if(mapp[a][i])
if(!--in[i]) q.push(i);
}
if(cnt==n) return 1;
return 0;
}
int main()
{
while(cin>>n>>m,n+m)
{
fill(in,in+maxn,0);
fill(&mapp[0][0],&mapp[maxn][0],0);
while(m--)
{
int a,b;
cin>>a>>b;
if(!mapp[a][b]) mapp[a][b]=1,in[b]++;//注意,一大坑点,可能会有重边
}
int flag = tuopu();
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
2.邻接表
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#define maxn 111
using namespace std;
vector<int>G[maxn];
int in[maxn],n,m;
int tuopu()
{
int cnt = 0;
queue<int>q;
for(int i=0;i<n;i++) if(!in[i]) q.push(i);
while(!q.empty())
{
int temp = q.front();
q.pop();
cnt++;
for(int i=0;i<G[temp].size();i++)
{
int a = G[temp][i];
cout<<a<<endl;
if(!--in[a]) q.push(a);
}
}
if(cnt==n) return 1;
return 0;
}
int main()
{
int a,b;
while(cin>>n>>m,n+m)
{
for(int i=0;i<n;i++) G[i].clear();
fill(in,in+maxn,0);
while(m--)
{
cin>>a>>b;
G[a].push_back(b);
in[b]++;
}
int flag = tuopu();
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}