题目描述
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输出一个序列,使得每个人的孩子都比那个人后列出。
输入格式
第 1 行一个整数 n,表示家族的人数;
接下来 n 行,第 i 行描述第 i 个人的孩子;
每行最后是 0 表示描述完毕。
每个人的编号从 1 到 n。
输出格式
输出一个序列,使得每个人的孩子都比那个人后列出;
数据保证一定有解,如果有多解输出任意一解。
样例
数据范围
1≤n≤100
输入样例:
5
0
4 5 1 0
1 0
5 3 0
3 0
输出样例:
2 4 5 3 1
算法1
C++ 代码
#include<queue>//无环有向边 拓扑排序 这类问题就是有因必有果(有向 无环)
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1000000
using namespace std;
int n;
int idx;//位置
int d[N];//入度
int e[N],h[N],ne[N];//h为各个点的头节点
queue<int>q;
void add(int a,int b){//在a b之间连一条边
e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
int main(){
memset(h,-1,sizeof h);
scanf("%d",&n);
for(int i=1;i<=n;i++){//初始化连图
int b;
while(scanf("%d",&b)&&b){
add(i,b);
d[b]++;
}
}
for(int i=1;i<=n;i++){//找到第一个入度为0的点
if(d[i]==0)q.push(i);//将i入队 不一定初始时只有一个入度为0的 故不可break
}
while(!q.empty()){
int t=q.front();
q.pop();
printf("%d ",t);
for(int i=h[t];i!=-1;i=ne[i]){//遍历t指向所有的点 找出最小的点
// i为地址 e[i]中才为指向的点
d[e[i]]--;
if(d[e[i]]==0)q.push(e[i]);
}
}
return 0;
}
```