acwing \1191. 家谱树
题目描述
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输出一个序列,使得每个人的孩子都比那个人后列出。
输入格式
第 11 行一个整数 nn,表示家族的人数;
接下来 nn 行,第 ii 行描述第 ii 个人的孩子;
每行最后是 00 表示描述完毕。
每个人的编号从 11 到 nn。
输出格式
输出一个序列,使得每个人的孩子都比那个人后列出;
数据保证一定有解,如果有多解输出任意一解。
数据范围
1≤n≤1001≤n≤100
输入样例:
5 0 4 5 1 0 1 0 5 3 0 3 0
输出样例:
2 4 5 3 1
拓扑排序模板题
分析
topo排序,记录排序顺序即可
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 110;
int n;
int deg[N]; // 入度
vector<int> h[N];
int res[N];
int cnt = 0;
void add(int a, int b)
{
// a->b
h[a].push_back(b);
}
void topo()
{
queue<int> q;
for(int i = 1; i <= n; i++)
if(!deg[i]) q.push(i), res[cnt++] = i;
while(q.size())
{
int t = q.front();
q.pop();
for(int i = 0; i < h[t].size(); i++)
{
int j = h[t][i];
deg[j]--;
if(!deg[j]) q.push(j), res[cnt++] = j;
}
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
while(true)
{
int x;
scanf("%d", &x);
if(!x) break;
add(i, x);
deg[x]++;
}
}
// printf("%d", res);
topo();
for(int i = 0; i < cnt; i++) printf("%d ", res[i]);
return 0;
}