拓扑排序概念:在一个有向图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。
过程:先统计所有节点的入度,对于入度为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;
}