Definition
Because the definition of source and sink has been removed, we need to redefine the concept of a cut.
(In fact, the definition of a cut in the network-flow context differs from that on Wikipedia; because the cuts most commonly encountered are minimum-cut problems with a source and a sink, this terminology has become conventional.)
Cut
A set of edges whose removal makes a flow network no longer connected (that is, splits it into two subgraphs) is called a cut of the graph.
In other words: in an undirected graph , let be a set of edges in graph . If deleting from all edges in makes disconnected, then is called a cut of .
Minimum-cut problem with a source and a sink
Same as the definition in minimum cut.
Minimum-cut problem without a source or a sink
A cut whose edges have the minimum total weight. It is also called the global minimum cut.
Clearly, the complexity of directly running a network flow algorithm is too high.
Stoer–Wagner Algorithm
Introduction
The Stoer–Wagner algorithm was proposed in 1995 by Mechthild Stoer and Frank Wagner. It solves the global minimum-cut problem on undirected graphs with positive edge weights by recursively contracting vertices.
Properties
The time complexity is , which is generally approximated as .
Its implementation is based on the following basic fact: let graph contain any two vertices . Then for graph , any cut either has in the same connected component, or is an cut.
Procedure
- Choose any two vertices in graph , namely , use them as the source and sink, and find graph 's minimum cut (called a cut of phase), then update the current answer.
- “Contract” vertices . If graph has greater than , return to the first step.
- Output the minimum of all cuts of phase.
To contract vertices : remove the edge between , namely . For any vertex in , say , remove and add its edge weight to .
Explanation: if are in the same connected component, consider and a vertex in it. If , then must also hold; otherwise, since are connected, are connected, which would make lie in the same connected component, and then would be better than . The converse is analogous. Therefore, can be regarded as one vertex.
Step 1 considers the case where are not in the same connected component, and step 2 considers the remaining case. Since each execution of step 2 decreases by , the algorithm terminates after executions.
Finding the S-T minimum cut
(Clearly, this is not network flow.)
Suppose that after several contractions the current graph is , and we execute step 1.
We construct a set , initially setting .
At each step, among all vertices in , we add a vertex satisfying and maximizing the weight function to , until .
The weight function is defined as follows:
(If , then .)
It is easy to see that the order in which all vertices are added to is fixed. Let denote the vertex added in position in , and let ; let denote the order in which is added to , namely the size of after is added.
Then, for any vertex , an -to- cut has weight .
Proof
Define a vertex to be activated if and only if, when is added to , the last vertex in , , was added earlier than , and in the graph , and are not in the same connected component.

As shown in the figure, the blue and yellow regions are two different connected components; the numbers in brackets indicate the order in which vertices are added to . Gray vertices are activated, while white vertices are not activated.
Define , that is, the set of vertices added strictly before to . Let be the edge set of the subgraph of induced by the vertex set . (Note that it includes vertex .)
Define the induced cut as . .
Lemma 1
For any activated vertex , .
Proof: use mathematical induction.
For the first activated vertex , by definition, .
For two subsequent activated vertices , assume . Then:
We also know that:
and , so:
Since contributes to but not to , and all edges have positive weights, we obtain:
This proves the claim by induction.
Since and are not in the same connected component, is activated. Therefore, .
P5632 [Template] Stoer–Wagner Algorithm
#include <cstring>
#include <iostream>
using namespace std;
constexpr int N = 601;
int fa[N], siz[N], edge[N][N];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int dist[N], vis[N], bin[N];
int n, m;
int contract(int &s, int &t) { // Find s,t
memset(dist, 0, sizeof(dist));
memset(vis, false, sizeof(vis));
int i, j, k, mincut, maxc;
for (i = 1; i <= n; i++) {
k = -1;
maxc = -1;
for (j = 1; j <= n; j++)
if (!bin[j] && !vis[j] && dist[j] > maxc) {
k = j;
maxc = dist[j];
}
if (k == -1) return mincut;
s = t;
t = k;
mincut = maxc;
vis[k] = true;
for (j = 1; j <= n; j++)
if (!bin[j] && !vis[j]) dist[j] += edge[k][j];
}
return mincut;
}
constexpr int inf = 0x3f3f3f3f;
int Stoer_Wagner() {
int mincut, i, j, s, t, ans;
for (mincut = inf, i = 1; i < n; i++) {
ans = contract(s, t);
bin[t] = true;
if (mincut > ans) mincut = ans;
if (mincut == 0) return 0;
for (j = 1; j <= n; j++)
if (!bin[j]) edge[s][j] = (edge[j][s] += edge[j][t]);
}
return mincut;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m;
if (m < n - 1) {
cout << 0;
return 0;
}
for (int i = 1; i <= n; ++i) fa[i] = i, siz[i] = 1;
for (int i = 1, u, v, w; i <= m; ++i) {
cin >> u >> v >> w;
int fu = find(u), fv = find(v);
if (fu != fv) {
if (siz[fu] > siz[fv]) swap(fu, fv);
fa[fu] = fv, siz[fv] += siz[fu];
}
edge[u][v] += w, edge[v][u] += w;
}
int fr = find(1);
if (siz[fr] != n) {
cout << 0;
return 0;
}
cout << Stoer_Wagner();
return 0;
}
Complexity Analysis and Optimization
The complexity of the contract operation is .
There are contract operations in total, so the overall complexity is .
As with shortest paths, the bottleneck of the algorithm is finding the vertex with the maximum weight.
One contract operation requires finding the heap maximum times and incrementally updating edge weights times.
A Fibonacci heap can perform heap-maximum queries in time and incremental weight updates in time, giving a theoretical complexity of . However, Fibonacci heaps have large constants and require a lot of code, so their practical value is low.
(In actual tests, even enabling O2 requires the judge's performance fluctuations to be favorable in order to pass.)