家谱树

197 阅读2分钟

·开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 26 天,点击查看活动详情

  1. 家谱树

有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。

给出每个人的孩子的信息。

输出一个序列,使得每个人的孩子都比那个人后列出。

输入格式

第 11 行一个整数 n�,表示家族的人数;

接下来 n� 行,第 i� 行描述第 i� 个人的孩子;

每行最后是 00 表示描述完毕。

每个人的编号从 11 到 n�。

输出格式

输出一个序列,使得每个人的孩子都比那个人后列出;

数据保证一定有解,如果有多解输出任意一解。

数据范围

1≤n≤1001≤�≤100

输入样例:

5
0
4 5 1 0
1 0
5 3 0
3 0

输出样例:

2 4 5 3 1

分析

拓扑排序的板子题,先把入度为0的点入队,然后循环遍历,把每个人的儿子找出来,存到tup数组里面,然后的倒序输出tup数组就ok了

代码

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=10010;
int d[N],idx=0,e[N],ne[N],h[N];
int tup[N],cnt=0;
inline void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
queue<int> q;
inline void tp(){
    while(q.size()){
        int t=q.front();
        tup[++cnt]=t;
        q.pop();
        for(int i=h[t];~i;i=ne[i]){
            int j=e[i];
            d[j]--;
            if(d[j]==0) q.push(j);
        }
    }
}
int main(){
    cin>>n;
    memset(d,0,sizeof d);
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++){
        int x;
        while(cin>>x){
            if(x==0) break;
            add(x,i);
            d[i]++;
        }
    }
    for(int i=1;i<=n;i++){
        if(d[i]==0) q.push(i);
    }
    tp();
    for(int i=n;i;i--){
        cout<<tup[i]<<" ";
    }
    return 0;
}

希望能帮助到大家,qaq!