拓扑排序
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
1. 有向无环图
在图论中,如果一个有向图无法从某个顶点出发经过若干条边回到该点,即不应该带有回路,则这个图是一个有向无环图(DAG图)。
因为有向图中一个点经过两种路线到达另一个点未必形成环,因此有向无环图未必能转化成树,但任何有向树均为有向无环图。
性质:有向无环图的生成树个数等于入度非零的节点的入度积。
2. 拓扑序列
在AOV网中(一个AOV网应该是一个有向无环图,即不应该带有回路。),若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我 们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作 它的拓扑序列。
3.拓扑排序
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。
家谱树
【题目描述】
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输入一个序列,使得每个人的后辈都比那个人后列出。
【输入】
第一行一个整数(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
1 #include<stdio.h> 2 3 int n; 4 int m,cnt; 5 int r[105],c[105],a[105][105]; 6 int ans[105]; 7 8 int main(){ 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++){ 11 int x; 12 scanf("%d",&x); 13 while(x!=0){ 14 c[i]++;// 第i个出度++ 15 a[i][c[i]]=x;//第i个人第c【i】个出度是x 16 r[x]++;//x入度++ 17 scanf("%d",&x); 18 } 19 } 20 21 for(int i=1;i<=n;i++) 22 if(r[i]==0)ans[++cnt]=i;//找入度为0的点的个数 23 24 int x; 25 while(m!=n){ 26 x=ans[cnt];//第一个入读为0 27 printf("%d ",x); 28 cnt--;//入度为0点个数-- 29 m++;//已输出人数++ 30 for(int i=1;i<=c[x];i++){ 31 r[a[x][i]]--;//入度为0点和他相连所有边终点入度-- 32 if(r[a[x][i]]==0)ans[++cnt]=a[x][i];//如果点入度==0,进队 33 } 34 } 35 return 0; 36 }