10/16/2018 Topological Sort (Directed Acyclic Graph)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值