Chapter 11. Network Flow
Classical augmenting-path max-flow algorithms (FordFulkerson, EdmondsKarp).
This page: Classical forms. View LLP forms »
This page collects the classical / sequential implementations of the algorithms developed in this chapter. The lattice-linear (LLP) reformulations and chapter setup live on the LLP companion page.
FordFulkerson
DFS-based augmenting-path scheme. The aux augmentingPath performs a DFS
on the residual graph and writes a parent pointer for every reachable vertex; on
success the main loop walks the parent chain back from $t$ to $s$ to find the
bottleneck and pushes that much flow along every edge of the path
(reverse-edge augmentations decrement the forward flow).
Time complexity: $O(|f^{*}| \cdot (n + m))$ — pseudo-polynomial in the maximum-flow value $|f^{*}|$.
int[][] maxflow(int[][] c, int s, int t) {
int n = c.length;
int[][] f = new int[n][n];
int[] parent = new int[n];
boolean done = false;
while (!done) {
int found = augmentingPath(c, f, s, t, parent);
if (found == 0) {
done = true;
} else {
int bottleneck = 2147483647;
int v = t;
while (v != s) {
int u = parent[v];
int r = residual(c, f, u, v);
if (r < bottleneck) {
bottleneck = r;
};
v = u;
};
v = t;
while (v != s) {
int u = parent[v];
f[u][v] = f[u][v] + bottleneck;
f[v][u] = f[v][u] - bottleneck;
v = u;
}
}
};
return f;
}
EdmondsKarp
Same outer skeleton as FordFulkerson, but augmenting paths are shortest (fewest residual edges) — found via BFS rather than DFS. This single change is what makes the algorithm strongly polynomial at $O(|V| \cdot |E|^2)$.
Time complexity: $O(n \cdot m^2)$, strongly polynomial.
int[][] maxflow(int[][] c, int s, int t) {
int n = c.length;
int[][] f = new int[n][n];
int[] parent = new int[n];
boolean done = false;
while (!done) {
int found = bfsResidual(c, f, s, t, parent);
if (found == 0) {
done = true;
} else {
int bottleneck = 2147483647;
int v = t;
while (v != s) {
int u = parent[v];
int r = c[u][v] - f[u][v];
if (r < bottleneck) {
bottleneck = r;
};
v = u;
};
v = t;
while (v != s) {
int u = parent[v];
f[u][v] = f[u][v] + bottleneck;
f[v][u] = f[v][u] - bottleneck;
v = u;
}
}
};
return f;
}