Algorithm

int edmondsKarp(int[][] cap, int s, int t) {
  int flow = 0;
  while (true) {
    int[] parent = new int[V];
    Arrays.fill(parent, -1);
    parent[s] = s;
    Deque q = new ArrayDeque<>();
    q.offer(s);
    while (!q.isEmpty() && parent[t] == -1) {
      int u = q.poll();
      for (int v = 0; v < V; v++)
        if (parent[v] == -1 && cap[u][v] > 0) {
          parent[v] = u; q.offer(v);
        }
    }
    if (parent[t] == -1) break;
    int bottleneck = Integer.MAX_VALUE;
    for (int v = t; v != s; v = parent[v])
      bottleneck = Math.min(bottleneck, cap[parent[v]][v]);
    for (int v = t; v != s; v = parent[v]) {
      cap[parent[v]][v] -= bottleneck;
      cap[v][parent[v]] += bottleneck;
    }
    flow += bottleneck;
  }
  return flow;
}
Advertisement

Complexity proof

Distance from s to t in residual is non-decreasing. Each edge is 'saturating' O(V) times → O(V·E) BFS ops → O(V·E²) total.

Advertisement

vs Ford-Fulkerson generic

Same result. Guaranteed polynomial time.

Practice

Fine for medium graphs. Beaten by Dinic's on large graphs.