Minimum Directed Spanning Tree
Definition
The Minimum Spanning Tree on a directed graph is called the Directed Minimum Spanning Tree (DMST).
A commonly used algorithm is the Chu–Liu/Edmonds algorithm (also known as Edmonds' algorithm), which can solve the DMST problem in \(O(nm)\) time.
Process
- For each vertex, select the incoming edge with the smallest weight.
- If no cycle exists, the algorithm terminates; otherwise, contract the cycle and update the distances from other vertices to the cycle.
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
Tarjan's DMST Algorithm
Tarjan proposed an algorithm that can solve the DMST problem in \(O(m+n\log n)\) time.
The algorithm description and reference code here are based on Professor Uri Zwick's lecture notes. More details can be found in the original text.
Process
Tarjan's algorithm consists of two phases: contraction and expansion. We first describe the contraction phase.
We assume the input graph is strongly connected. If not, add \(O(n)\) edges with infinite weight to make it strongly connected.
We need a heap to store information such as the index of incoming edges, their weights, and the total cost of vertices. Since heap merging operations will occur later, we implement it using Leftist Tree and Union-Find. In each step, the algorithm selects an arbitrary vertex \(v\), ensuring \(v\) is not the root and has no incoming edge in the heap. Then, add \(v\)'s minimum incoming edge to the heap. If this newly added edge forms a cycle in the heap, contract the vertices in the cycle into a super-vertex. Continue this process until all vertices are contracted into a single super-vertex, at which point the contraction phase ends. After contraction, a contraction tree is obtained, which will then be expanded.
The edges in the heap always form a path \(v_0\leftarrow v_1\leftarrow \dots\leftarrow v_k\). Since the graph is strongly connected, this path must exist, and each \(v_i\) may be an original vertex or a contracted super-vertex.
Initially, let \(v_0=a\), where \(a\) is an arbitrary vertex in the graph. Each time, select a minimum incoming edge \(v_k\leftarrow u\). If \(u\) is not among \(v_0,v_1,\dots,v_k\), extend the path to \(v_{k+1}=u\). If \(u\) is one of them, say \(v_i\), then a cycle \(v_i\leftarrow\dots\leftarrow v_k\leftarrow v_i\) is found. Contract these vertices into a super-vertex \(c\).
Place all vertices or super-vertices into a queue \(P\), and initially select an arbitrary vertex \(a\). While the queue is not empty, perform the following steps:
- Select \(a\)'s minimum incoming edge, ensuring no self-loop, and find the other endpoint \(b\). If \(b\) has not been recorded, no cycle is formed. Set \(a\leftarrow b\) and continue searching for a cycle.
- If \(b\) has been recorded, a cycle is detected. Increase the total vertex count, renumber all vertices in the cycle, merge heaps, and update the total weights of vertices/super-vertices. The weight update involves collecting all incoming edges on the cycle and subtracting the weight of the cycle's incoming edge.

As shown in the figure, the strongly connected graph on the left contracts into the contraction tree on the right. Here, \(a\) is the super-vertex formed by contracting vertices 1 and 2; \(b\) is the super-vertex formed by contracting vertices 3, 4, and 5; and \(A\) is formed by contracting super-vertices \(a\) and \(b\).
The expansion phase is relatively straightforward. Starting from the required root \(r\), expand every cycle on the path from \(r\) to the root of the contraction tree. Then, starting from \(r\)'s ancestor \(f_r\), expand the cycle from \(f_r\) to the root, until all vertices are processed.
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
References
Uri Zwick. (2013), Directed Minimum Spanning Trees, Lecture notes on "Analysis of Algorithms"
https://riteme.site/blog/2018-6-18/mdst.html#_3
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用