Concepts
Cut
For a flow network , a cut is a partition of vertices: partition all vertices into two sets and , where the source and the sink .
Capacity of a cut
The capacity of a cut is the sum of the capacities of all edges from to , namely . We may also write for .
Minimum cut
A minimum cut is a cut whose capacity is minimum.
Proof
Max-flow min-cut theorem
See the section on the max-flow min-cut theorem on the maximum flow page.
Code
Minimum cut
By the max-flow min-cut theorem, we can directly obtain the following code:
Reference implementation
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
constexpr int N = 1e4 + 5, M = 2e5 + 5;
int n, m, s, t, tot = 1, lnk[N], ter[M], nxt[M], val[M], dep[N], cur[N];
void add(int u, int v, int w) {
ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, val[tot] = w;
}
void addedge(int u, int v, int w) { add(u, v, w), add(v, u, 0); }
int bfs(int s, int t) {
memset(dep, 0, sizeof(dep));
memcpy(cur, lnk, sizeof(lnk));
std::queue<int> q;
q.push(s), dep[s] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = lnk[u]; i; i = nxt[i]) {
int v = ter[i];
if (val[i] && !dep[v]) q.push(v), dep[v] = dep[u] + 1;
}
}
return dep[t];
}
int dfs(int u, int t, int flow) {
if (u == t) return flow;
int ans = 0;
for (int &i = cur[u]; i && ans < flow; i = nxt[i]) {
int v = ter[i];
if (val[i] && dep[v] == dep[u] + 1) {
int x = dfs(v, t, std::min(val[i], flow - ans));
if (x) val[i] -= x, val[i ^ 1] += x, ans += x;
}
}
if (ans < flow) dep[u] = -1;
return ans;
}
int dinic(int s, int t) {
int ans = 0;
while (bfs(s, t)) {
int x;
while ((x = dfs(s, t, 1 << 30))) ans += x;
}
return ans;
}
int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
while (m--) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
printf("%d\n", dinic(s, t));
return 0;
}
Partition
Starting DFS from the source and traversing edges with residual capacity greater than each time, we can find all vertices in the set .
void dfs(int u) {
vis[u] = 1;
for (int i = lnk[u]; i; i = nxt[i]) {
int v = ter[i];
if (!vis[v] && val[i]) dfs(v);
}
}
Number of cut edges
If the number of cut edges must be minimized subject to a minimum cut, first find a minimum cut, change the capacities of edges that are not saturated to and those that are saturated to , and run minimum cut again. If there is no minimum-cut constraint, simply set every edge capacity to and find a minimum cut.
Problem model 1
There are items and two sets . Not putting an item into costs , and not putting it into costs . There are also constraints of the form , meaning that if and are not in the same set, the cost is . Every item must belong to exactly one set; find the minimum cost.
This is a classic choose-one-of-two minimum-cut problem. Use a source and sink for the two sets; for vertex , add an edge of capacity from and an edge of capacity to . For a constraint , add a bidirectional edge of capacity between and $v.
When the source and sink are disconnected, the vertices on each side represent the choices of the two sets. Cutting an edge incident to or means not putting the item in or ; cutting an edge between items means that the two items are not put in the same set.
The minimum cut is the minimum cost.
Problem model 2
A maximum-weight closure problem gives a directed graph in which every vertex has a weight (positive, negative, or ). Choose a subgraph with maximum total weight such that every successor of every vertex in the subgraph is also in the subgraph.
Construct a super-source and super-sink . If vertex has positive weight, add a directed edge from to whose capacity is its weight; if has negative weight, add a directed edge from to whose capacity is the opposite of its weight. Set the capacities of all original edges to . Run maximum flow; the sum of all positive weights minus the maximum flow is the answer.
We prove several small claims:
- Every valid subgraph corresponds to a cut in the flow network. A cut divides the network into two parts, and the part connected to has no edge directed to the other part, so it satisfies the condition above. This correspondence is an if and only if.
- Every edge removed by a minimum cut must be incident to either or . Otherwise its capacity is , so it cannot belong to a minimum cut.
- The weight sum of the chosen subgraph the sum of all positive weights the sum of the positive weights of unchosen vertices the sum of the negative weights of chosen vertices. When a positive-weight vertex is not chosen, its edge to is cut; when a negative-weight vertex is chosen, its edge to is cut. The sum of the capacities of the cut edges is the cut capacity. Thus the expression becomes: weight sum sum of all positive weights cut capacity.
- Therefore, the maximum weight sum the sum of all positive weights the minimum cut the sum of all positive weights the maximum flow.