題目大意:有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;
}