原题
【题目描述】
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输出一个序列,使得每个人的后辈都比那个人后列出。
【输入】
第1行一个整数N𝑁(1≤N≤1001≤𝑁≤100),表示家族的人数;
接下来N𝑁行,第i𝑖行描述第i𝑖个人的儿子;
每行最后是00表示描述完毕。
【输出】
输出一个序列,使得每个人的后辈都比那个人后列出;
如果有多解输出任意一解。
【输入样例】
5
0
4 5 1 0
1 0
5 3 0
3 0
【输出样例】
2 4 5 3 1
题目分析
拓扑排序
题目给定了人之间的关系(谁是谁的后代),可以转化为父亲指向孩子的单向边
对于每一个节点(人)可以确定这个节点的入度(祖先个数)当他的入度为0时他就是最大的祖先,输出即可,之后再将他所链接的边的入度减一,判断这个节点入度是否为0
重复以上过程即可
AC代码
#include<bits/stdc++.h>
using namespace std;
const int SIZN = 105;
const int SIZM = 5050;
int n;
int in[SIZN];
queue<int> q;
int head[SIZN], to[SIZM], nxt[SIZM],cnt;
void add(int u, int v)
{
nxt[++cnt] = head[u];
to[cnt] = v;
head[u] = cnt;
}
signed main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
int peo;
while (true)
{
cin >> peo;
if (peo == 0)break;
add(i, peo);
in[peo]++;
}
}
for (int i = 1; i <= n; i++)
{
if (in[i] == 0)
{
q.push(i);
}
}
while (!q.empty())
{
const int u = q.front();
q.pop();
cout << u << ' ';
for (int i = head[u]; i; i = nxt[i])
{
const int v = to[i];
in[v]--;
if (in[v] == 0)q.push(v);
}
}
return 0;
}