先来认识一下有向无环图:一个有向图的任意顶点都无法通过一些有向边回到该点自身,就称之为有向无环图。
对于拓扑排序,是根据边的先后顺序来进行排列,比如:u->v,表示点可以由u到达v,那么u就要排在v的前面,如果两者之间的层数相同,那么就可以任意的排列,当然有的时候题目会限制,比如按照编号大小来进行排列。
看这个图,我们已经标明了它们的边的指向,1,3都是可以当作起点,因为它们都是属于第一层的点,1->2,说明1排在2的前面,然后我们发现4可以由2,3都可以指向,则2,3一定要在4的前面,所以我们目前为止可以排成1,2,3,4或者1,3,2,4都是符合我们拓扑排序的,然后5要在3的后面,7要在5的后面,6要在4,7的后面,8要在6,7的后面,最后,我们排下来就是如下的顺序,这只是一种合法的顺序:1,3,2,4,5,7,6,8。至于为什么这个排列会有几种的情况呢?而不是和我们的冒泡,快排等的那样只有一种的结果,这是因为我们衡量的标尺不一样,我们那个是按照数值的大小来进行衡量的,而这个是我们按照先后的顺序来进行衡量的。这个可不必追究。
接下来,我们来说说怎么实现拓扑排序。
由于这个是按照先后顺序的标尺进行排列的,这个就和我们STL里面的队列十分的契合。那么我们就可以想到由队列来进行模拟排列。开一个inDgree数组,我们在输入边的关系的时候一边更新我们的结点的深度,就是最开始的我们记为0.然后对于他可以到达的结点,在前一个结点的基础上加上1,注意,这里是求它的所有的前一个结点的度之和,比如有3个结点可以到达这个结点,那么这个结点的度就是在三个结点的原有的度都加1然后求和就是了。然后再排序的时候,我们将度为0的结点入队,然后找出这些结点的子节点,让它们的度都-1,直到度为0的时候入队即可。
代码:
const int m