更新:
拓扑排序有2中方法(最后结果可能不同,因为拓扑排序有多解)。
一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后将它和它的边从图中删除。然后对剩余部分使用同样的操作。
public ArrayList<Integer> topo()
{
ArrayList<Integer> result = new ArrayList<>();
Queue<Integer> que = new LinkedList<>();
int[] ind = new int[V];
for(int i=0;i<V;i++)
ind[i] = 0;
for(LinkedList<Integer> nodes:adj)
for(int x:nodes)
ind[x]++;
for(int i=0;i<V;i++)
if(ind[i]==0)
que.offer(i);
while(!que.isEmpty())
{
int k = que.poll();
result.add(k);
for(int x:adj(k))
{
ind[x]--;
if(ind[x]==0)
que.offer(x);
}
}
return result;
}
定义: 拓扑排序是对有向无环图(DAG)的顶点的一种排序, 使得如果存在一条从v到w的路径,那么在排序中w就出现在v的后面。
如果图含有环,那么拓扑排序是不可能的。试想有3个正整数,a比b大,b比c大,c比a大,我们无法对abc排序。
算法:
1. 一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后将它和它的边从图中删除。然后对剩余部分使用同样的操作。
2. 另一种不那么直观,却更加简单的算法是求所有顶点的逆后序排列。
第二种方法:
所以我们要做的就是:
先判断该图是不是一幅有向无环图,如果是,则进行拓扑排序。在这个过程中,我们需要用dfs遍历该图2遍。
性能分析:
使用深度优先搜索对有向无环图进行拓扑排序所需的时间和V+E成正比。