A Systematic Approach to Algorithms

Vijay K. Garg · The University of Texas at Austin

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;
}