#include<bits/stdc++.h>
using namespace std;
int d[101];//d[i]表示i点的入度个数
int t[101][101];//t[i][j]表示i点到j点间有一条有向边
queue<int> q;//q表示当前入度为0的节点
int main(){
//所有数组初始化为0
memset(d, 0, sizeof(d));
memset(t, 0, sizeof(t));
int n;
cin >> n;//输入共有几人
for (int i = 1; i <= n; i++){
int tmp;
while(scanf("%d", &tmp) && tmp){//当没有到0时,输入当前这个人的子
d[tmp]++;//tmp这个点的入度数加1,因为tmp是i的子
t[i][tmp]++;//这条有向边从i点到tmp
}
}
int x = 0;//这个是答案的长度
for (int i = 1; i <= n; i++)//从头到尾
if (d[i] == 0)//当i点入度为0时
q.push(i);//将i点放入队列
while(!q.empty()){//拓扑排序
int u = q.front();//从队列里的第一个结点开始找他的有向边
q.pop();//用完即弃
cout << u << ' ';//输出这个结点
for (int i = 1; i <= n; i++)//删除与该结点相关的有向边并将相对应的结点入度减1
if (t[u][i]){
d[i]--;
if (d[i] == 0) q.push(i);//如果对应结点入度为0,将该结点放入队列
}
}
return 0;
}
这两天看拓扑排序,看了很多例子,但从没有一个能写的注释很清楚,于是结合自己的实践写了这个家谱树的解法,希望对大家学习图的相关算法有帮助