拓扑排序并不很常见,但也不容小觑,所以也要认真去做,不能马虎。
来一发定义:
拓扑排序算法,只适用于AOV网(有向无环图)。 把AOV网中的所有活动排成一个序列, 使得每个活动的所有前驱活动都排在该活动的前面,这个过程称为“拓扑排序”,所得到的活动序列称为“拓扑序列”。 一个AOV网的拓扑序列是不唯一的,例如下面的这张图,它的拓扑序列可以是:ABCDE,也可以是ACBDE,或是ADBCE。在下图所示的AOV网中,工程B和工程C显然可以同时进行,先后无所谓;但工程E却要等工程B、C、D都完成以后才能进行。
【例4-12】、家谱树 【问题描述】 有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。 给出每个人的孩子的信息。 输出一个序列,使得每个人的后辈都比那个人后列出。 【输入格式】 第1行一个整数N(1<=N<=100),表示家族的人数。 接下来N行,第I行描述第I个人的儿子。 每行最后是0表示描述完毕。 【输出格式】 输出一个序列,使得每个人的后辈都比那个人后列出。 如果有多解输出任意一解。 【输入样例】 5 0 4 5 1 0 1 0 5 3 0 3 0 【输出样例】 2 4 5 3 1
由题可知,当每个点的入度为0时,就轮到它输出了,然后把每个相连点的入度减一。
#include<iostream> using namespace std; int r[101],c[101],a[101][101]; int num,m,n,x,y,ans[105],tot = 0,temp; int main() { num = 0; cin>>n; for(int i = 1;i <= n;i++) { cin>>m; if(m != 0) { c[i]++; //每个点的出度 a[i][c[i]] = m; r[m]++; //每个点的入度 } else break; } for(int i = 1;i <= n;i++) { if(c[i] == 0) { ans[++tot] = i; } } do { temp = ans[tot]; cout<<temp; tot--; num++; for(int j = 1;j <= c[temp];j++) { r[a[temp][j]]--; if(r[a[temp][j]] == 0) { ans[++tot] = a[temp][j]; } } } while(num != n); return 0; }