Topological Sort: Topological sort of a Directed Acyclic Graph (DAG) is a linear ordering of the vertices in the DAG so that vertex u comes before vertex v if the edge (u -> v) exists in the DAG. Every DAG has least one and possibly more topological sort(s).
Description of the algorithm:
1. visit a node and its connecting point (directed) by using dfs. After visiting, push nodes you visited in a list and delete them as well as their related paths.
2. Do step 1 for every node in your graph, and the result list is the result of the topological sort.

Comment: In dfs2(u), we append u to the back of a list of explored vertices only after visiting all the subtrees below u in the DFS spanning tree (the connection to DFS). This will be in reversed order, but we can work around this issue by reversing the print order in the output phase.
Runtime for the above code snippet: O(V + E) -> same as DFS
The above code just generates the one topographical sort. What if we want all possible topographical sorts?
eg. Ordering Tasks, Uva 10395
假设有n个变量,还有m个二元组(u, v),分别表示变量u小于v。那么,所有变量从小到大排列到大起来应该是什么样子的呢?例如,假设有四个变量a, b, c, d,若已知a < b, c < b, d < c, 则这四个变量的排序的可能是a < b < c < d。尽管还有其他可能 (如 d < a < c < b),你只需要找出其中一个即可。
分析: 把每个变量看出一个点,“小于”关系看成有向边,则得到了一个有向图。这样,我们的任务实际上是把一个图的所有结点排序,使得每一条有向边(u, v) 对应的u都排在v的前面。若图中存在有向环,则不存在拓扑排序。(在本例中,如果 a < b, b < c, a > c, 则有环,但是不可能)在访问完一个结点之后把它加到当前拓扑排序的首部。
class TopologicalSort {
static int[] c;
static int[] topo;
static boolean[][] g;
static int t;
public void fill(boolean[][] graph) {
for (int i = 0; i < graph.length; i++) {
for (int j = 0; j < graph[0].length; j++) {
g[i][j] = graph[i][j];
}
}
t = graph.length;
}
public static boolean dfs(int u) {
c[u] = -1;
for (int i = 0; i < c.length; i++) {
// u -> i has an edge from u to i; notice that topological sort is in non-cycle directed graph
if (g[u][i] == true) {
if (c[i] < 0) return false; //there is a cycle
if (c[i] == 0 && !dfs(i)) return false; //the remaining dfs also works fine
}
c[u] = 1; topo[--t] = u;
return true;
}
}
public static boolean toposort() {
for (int u = 0; u < g.length; u++) {
if (!dfs(u)) return false;
}
return true;
}
}
Comment: can use the above algorithm to test if there is a cycle in the graph
本文深入探讨了拓扑排序的概念及其实现算法,特别是在有向无环图(DAG)中的应用。介绍了通过深度优先搜索(DFS)进行节点访问并生成拓扑排序列表的方法,以及如何检测图中是否存在环。此外,还提供了示例代码,展示了如何生成单一的拓扑排序,以及如何寻找所有可能的拓扑排序。
1150

被折叠的 条评论
为什么被折叠?



