拓撲排序概念:在一個有向圖中,對所有的節點進行排序,要求沒有一個節點指向它前面的節點。
過程:先統計所有節點的入度,對於入度爲0的節點就可以分離出來,然後把這個節點指向的節點的入度-1。重複此過程直至所有節點都被分離出來。 PS:如果最後不存在入度爲0的節點,那就說明有環,不存在拓撲排序,也就是很多題目的無解的情況 。
搞懂拓撲排序後,這個題目就是個模板題,代碼如下:
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int maxn=105;
queue<int> q;
vector<int> vi[maxn];
int in[maxn];//in[n]代表第n個節點的入度
int main(){
int n;
cin >> n;
for(int i=1;i<=n;i++){
int m;
cin >> m;
for(int j=0;j<m;j++){
int x;
cin >> x;
vi[i].push_back(x);
in[x]++;
}
}
for(int i=1;i<=n;i++) cout << in[i] << " ";
cout << endl;
for(int i=1;i<=n;i++){//n,節點總數
if(in[i]==0) q.push(i);//將入度爲0的點入隊
}
int cnt=0;//操作次數
while(!q.empty())//遍歷隊列
{
int p=q.front();//取出一個入度爲0的點
q.pop();
for(int i=0;i<vi[p].size();i++)//將入度爲0的點所指向的點的入度減一
{
int y=vi[p][i];
in[y]--;
if(in[y]==0){//如果剩下的點中出現入度爲0的點,將其入隊
q.push(y);
}
}
cnt++;
}
//如果cnt==n,代表所有的節點都可以被分離出來,即不存在環
if(cnt==n) cout << 1 << endl;
else cout << 0 << endl;
return 0;
}