Maximum Weight Bipartite Matching
The maximum weight matching in a bipartite graph refers to the matching with the maximum sum of edge weights.
Hungarian Algorithm (Kuhn–Munkres Algorithm)
The Hungarian algorithm, also known as the KM algorithm, can find the maximum weight perfect matching of a bipartite graph in \(O(n^3)\) time.
Considering that the numbers of vertices in the two sets of a bipartite graph are not always equal, to apply the KM algorithm to solve the maximum weight matching problem, the following preprocessing is required: add dummy vertices to the smaller set to make both sides have the same number of vertices, and set the weight of non-existent edges to \(0\). In this case, the problem is transformed into finding a maximum weight perfect matching, which can then be solved using the KM algorithm.
Feasible Labeling
Assign a weight \(l(i)\) to each vertex \(i\), such that for all edges \((u,v)\), \(w(u,v) \leq l(u) + l(v)\).
Equality Subgraph
The spanning subgraph of the original graph under a feasible labeling, containing all vertices but only including edges \((u,v)\) that satisfy \(w(u,v) = l(u) + l(v)\).
Theorem 1: For a feasible labeling, if its equality subgraph has a perfect matching, then that matching is the maximum weight perfect matching of the original bipartite graph.
Proof 1.
Consider any perfect matching \(M\) of the original bipartite graph. Its edge weight sum is
\(val(M) = \sum_{(u,v)\in M} {w(u,v)} \leq \sum_{(u,v)\in M} {l(u) + l(v)} \leq \sum_{i=1}^{n} l(i)\)
The edge weight sum of any perfect matching \(M'\) in the equality subgraph of a feasible labeling is
\(val(M') = \sum_{(u,v)\in M} {l(u) + l(v)} = \sum_{i=1}^{n} l(i)\)
Thus, the edge weight sum of any perfect matching will not exceed \(val(M')\), meaning \(M'\) is the maximum weight matching.
With Theorem 1, our goal is to continuously adjust the feasible labeling so that the equality subgraph contains a perfect matching.
Since both sides have the same number of vertices, assume the number is \(n\). Let \(lx(i)\) denote the label of the \(i\)-th vertex on the left, \(ly(i)\) denote the label of the \(i\)-th vertex on the right, and \(w(u,v)\) denote the weight between the \(u\)-th vertex on the left and the \(v\)-th vertex on the right.
First, initialize a feasible labeling, for example:
\(lx(i) = \max_{1\leq j\leq n} \{ w(i, j)\},\, ly(i) = 0\)
Then, select an unmatched vertex and find an augmenting path as in maximum matching. If an augmenting path is found, augment it; otherwise, an alternating tree is obtained.
Let \(S\) and \(T\) denote the vertices on the left and right sides of the bipartite graph that are in the alternating tree, and \(S'\) and \(T'\) denote those not in the alternating tree.

In the equality subgraph:
- Edges \(S-T'\) do not exist; otherwise, the alternating tree would grow.
- Edges \(S'-T\) must be non-matching edges; otherwise, they would belong to \(S\).
Suppose we subtract \(a\) from the labels of vertices in \(S\) and add \(a\) to the labels of vertices in \(T\). We observe:
- Edges \(S-T\) remain in the equality subgraph.
- Edges \(S'-T'\) remain unchanged.
- For edges \(S-T'\), \(lx + ly\) decreases, possibly allowing them to join the equality subgraph.
- For edges \(S'-T\), \(lx + ly\) increases, so they cannot join the equality subgraph.
Thus, the value \(a\) must be the minimum edge weight among \(S-T'\):
\(a = \min \{ lx(u) + ly(v) - w(u,v) | u\in{S} , v\in{T'} \}\).
When a new edge \((u,v)\) joins the equality subgraph, two cases arise:
- \(v\) is an unmatched vertex, then an augmenting path is found.
- \(v\) is already matched to a vertex in \(S'\).
After at most \(n\) label adjustments, an augmenting path can be found.
Each time the labels are adjusted, edges in the alternating tree do not leave the equality subgraph, so we can maintain this tree directly.
For each vertex \(v\) in \(T\), maintain:
\(slack(v) = \min \{ lx(u) + ly(v) - w(u,v) | u\in{S} \}\).
Thus, the adjustment value \(a\) can be computed in \(O(n)\):
\(a = \min \{ slack(v) | v\in{T'} \}\)
When a new vertex joins \(S\) in the alternating tree, \(slack(v)\) needs to be updated in \(O(n)\). Adjusting labels requires subtracting \(a\) from each \(slack(v)\) in \(O(n)\). Once the alternating tree finds an unmatched vertex, an augmenting path is found.
Initially, enumerate \(n\) vertices to find augmenting paths. To find an augmenting path, the alternating tree needs to be extended \(n\) times, each extension requiring \(n\) maintenance operations, resulting in a total of \(O(n^3)\).
Reference Code
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 | |
Dynamic Hungarian Algorithm
Original paper: The Dynamic Hungarian Algorithm for the Assignment Problem with Changing Costs
Paper with clearer pseudocode: A Fast Dynamic Assignment Algorithm for Solving Resource Allocation Problems
Related OJ problem: DAP
Algorithm Idea
- Modify the weights between a single vertex \(u_i\) and all \(v_j\), i.e., a row in the weight matrix.
- Update label \(lx(u_i) = max(w_{ij} - v_{j}), \forall j\)
- Delete matches related to \(u_i\)
- Modify the weights between all \(u_i\) and a single vertex \(v_j\), i.e., a column in the weight matrix.
- Update label \(ly(v_j) = max(w_{ij} - u_{i}), \forall i\)
- Delete matches related to \(v_j\)
- Modify the weight between a single vertex \(u_i\) and a single vertex \(v_j\), i.e., a single element in the weight matrix.
- Perform either operation 1 or 2.
- Add a single vertex \(u_i\) or a single vertex \(v_j\), i.e., add or delete a row or column in the weight matrix.
- Correspondingly perform operation 1 or 2. Note that adding a vertex here only adds the vertex without setting additional weight values; the weight between the new vertex and others is 0.
Algorithm Proof
- Let the original graph be G, with left and right labels \(\alpha^{i}\) and \(\beta^{j}\), and feasible labeling l. Then \(G_l\) is a subgraph of G, containing vertices and edges from G that satisfy \(w_{ij} = alpha_{i}+beta_{j}\).
- In the Hungarian algorithm section, Theorem 1 proves: For a feasible labeling, if its equality subgraph has a perfect matching, then that matching is the maximum weight perfect matching of the original bipartite graph.
- Assume the original optimal matching is \(M^*\). When a modification occurs, we update the feasible labeling according to the rules. Let the updated labels be \(\alpha^{i^*}\) or \(\beta^{j^*}\). The following situations may occur:
- An entire row of the weight matrix is modified. Let the modified row be \(i^*\), meaning all edges of \(v_{i^*}\) are modified. Thus, the original label of \(v_{i^*}\) may no longer satisfy the condition because we require \(w_{i^{*}j} \leq alpha_{i^*}+beta_{j}\). However, for other \(u_j\), except for edges related to \(i^*\), their edge weights remain unchanged, so their labels are still valid. Therefore, the algorithm modifies the labels related to \(v_{i^*}\) to make this set of labels a feasible labeling.
- An entire column of the weight matrix is modified. Similarly, the algorithm modifies the labels to make this set a feasible labeling.
- A single element of the weight matrix is modified. Arbitrarily modify one of the labels to satisfy the labeling condition.
- Each time the weight matrix is modified, it relates to a specific node, which may be on the left or right. Denote this node as \(x\). This node is matched with some node \(y\) in the original optimal matching. Each modification operation at most unpairs this pair of nodes. Therefore, we only need to run one round of the search in the Hungarian algorithm to obtain a new match, which, according to Theorem 1, is optimal.
The following code should be the code submitted by the second author of paper 2 (the following code is for maximizing weight; the original paper minimizes cost).
Dynamic Hungarian Algorithm Reference Code
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
Transformation to Min-Cost Max-Flow Model
Similar to Bipartite Maximum Matching, the maximum weight matching in a bipartite graph can also be transformed into a network flow problem.
First, add a source node and a sink node to the graph.
Connect the source node to each left vertex in the bipartite graph with an edge of capacity \(1\) and cost \(0\). Connect each right vertex in the bipartite graph to the sink node with an edge of capacity \(1\) and cost \(0\).
Next, for each edge in the bipartite graph connecting left vertex \(u\) and right vertex \(v\) with weight \(w\), add an edge from \(u\) to \(v\) with capacity \(1\) and cost \(w\).
Additionally, considering that in maximum weight matching, the number of matched edges may not equal the number of edges in a maximum matching, for each left vertex, also add an edge to the sink node with capacity \(1\) and cost \(0\).
Finding the maximum cost maximum flow of this network yields the answer. At this point, the maximum flow of the network must equal the number of left vertices, and the maximum cost under maximum flow corresponds to a maximum weight matching scheme.
Exercises
UOJ #80. Bipartite Maximum Weight Matching
Template problem
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 146 147 148 | |
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用