B3644 【模板】拓扑排序 / 家谱树
拓扑排序可前往这里学习。
题目描述
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。给出每个人的后代的信息。输出一个序列,使得每个人的后辈都比那个人后列出。
输入格式
第 1 1 1 行一个整数 N N N( 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100),表示家族的人数。接下来 N N N 行,第 i i i 行描述第 i i i 个人的后代编号 a i , j a_{i,j} ai,j,表示 a i , j a_{i,j} ai,j 是 i i i 的后代。每行最后是 0 0 0 表示描述完毕。
输出格式
输出一个序列,使得每个人的后辈都比那个人后列出。如果有多种不同的序列,输出任意一种即可。
输入输出样例 #1
输入 #1
5
0
4 5 1 0
1 0
5 3 0
3 0
输出 #1
2 4 5 3 1
思路
现在我们知道拓扑排序只能在有向无环图使用。
在此题中,如果一个人的祖宗已经全部输出,那么这个人就能输出,符合拓扑排序的思想。
对于一个有向无环图,只要把它的所有的入度为零的点入队,将所有与之相连的点的入度减一,找到新的入度为零的节点继续处理即可。
代码
#include<bits/stdc++.h>
using namespace std;
int n,ind[110];
vector<int>g[110];//vector存边
queue<int>q;
void tp()
{
while(!q.empty())
{
int k=q.front();
q.pop();
cout<<k<<" ";
for(auto i:g[k])
{
ind[i]--;//入度相应减少
if(!ind[i])
q.push(i);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
while(x!=0)
{
g[i].push_back(x);//建图
ind[x]++;//入度加1
cin>>x;
}
}
for(int i=1;i<=n;i++)
if(!ind[i])
q.push(i);//初始可输出节点
tp();
return 0;
}
更多推荐
所有评论(0)