Home
Day 20 · Week 4

Network Flow & Full-Course Review

Level 6 · Advanced + Capstone  ·  2 hrs: ~40 min flow · ~80 min review

🧠 Mental Model — Max Flow

Picture a network of pipes with capacities from a source to a sink. Maximum flow is the greatest rate you can push through. The recurring trick: repeatedly find an augmenting path with spare capacity and push flow along it, using residual edges that let you "undo" earlier choices.

Network flow is rare in standard interviews but appears at senior levels or when a problem secretly reduces to matching/assignment. Aim for awareness: recognize the reduction, know Edmonds-Karp exists.

⚙️ Ford-Fulkerson / Edmonds-Karp

  1. While an augmenting path from source to sink exists in the residual graph:
  2. Find one (Edmonds-Karp uses BFS → shortest augmenting path).
  3. Push flow = the path's minimum residual capacity (the bottleneck).
  4. Update residuals: subtract on forward edges, add on reverse edges.
Max-Flow Min-Cut Theorem (Ford & Fulkerson, 1956) The maximum flow from source to sink equals the minimum total capacity of any cut separating them.
Intuition Any flow is bounded by every cut's capacity (all flow crosses it). At termination no augmenting path remains, so the set of source-reachable residual vertices defines a cut whose capacity exactly equals the flow — matching the lower bound. Hence flow = min cut.
AlgorithmTimeNote
Ford-Fulkerson (DFS)O(E · maxflow)Only integral capacities; can be slow
Edmonds-Karp (BFS)O(V · E²)Shortest augmenting path; standard to cite
Dinic'sO(V² · E)Level graph + blocking flow; fast in practice

💻 Reference Implementation (Java)

Edmonds-Karp skeleton (BFS augmenting paths on a capacity matrix).

import java.util.*;

/** Edmonds-Karp max flow. cap[u][v] = capacity. Returns max flow s→t. */
public int maxFlow(int[][] cap, int s, int t, int n) {
    int flow = 0;
    while (true) {
        int[] parent = new int[n];
        Arrays.fill(parent, -1);
        parent[s] = s;
        Queue<Integer> q = new ArrayDeque<>();
        q.offer(s);
        while (!q.isEmpty() && parent[t] == -1) {   // BFS for augmenting path
            int u = q.poll();
            for (int v = 0; v < n; v++)
                if (parent[v] == -1 && cap[u][v] > 0) {
                    parent[v] = u;
                    q.offer(v);
                }
        }
        if (parent[t] == -1) break;          // no path ⇒ done

        int bottleneck = Integer.MAX_VALUE;      // min residual on path
        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]) {   // update residuals
            cap[parent[v]][v] -= bottleneck;
            cap[v][parent[v]] += bottleneck;           // reverse edge
        }
        flow += bottleneck;
    }
    return flow;
}

🎭 Problem Variances — when a problem is secretly max-flow

Disguise / phrasingReduces toTwist to handle
"Maximum bipartite matching"Max flow (unit capacities)Source→left→right→sink, cap 1
"Max # of edge/vertex-disjoint paths"Max flow (Menger)Unit caps; split vertices for vertex-disjoint
"Min cut to separate / sabotage network"Min cut = max flowCompute max flow, read the cut
"Assign tasks/workers with limits"Flow with capacitiesCapacities encode the limits
"Project selection / max profit with prereqs"Min-cut (closure)Classic max-flow reduction
"Escape the grid (multiple exits, no overlap)"Vertex-capacity flowSplit each cell into in/out with cap 1
Interview reality: you rarely code Dinic's live. The valuable skill is spotting the reduction ("this is bipartite matching → max flow") and stating min-cut = max-flow.

🗺️ Full-Course Master Recognition Table

The capstone cheat-sheet — map any graph problem to its algorithm in seconds.

SignalAlgorithmDay
Fewest steps, unweightedBFS2
Reachability, enumerate paths, region shapeDFS3
Count groups (undirected)Connected components4
Shortest path, non-negative weightsDijkstra7
Negative edges / bounded hopsBellman-Ford6
All-pairs shortest, small VFloyd-Warshall7
Weights ∈ {0,1}0-1 BFS6
Dynamic connectivity / merging groupsUnion-Find8–10
Dependency ordering (DAG)Topological sort11–12
Directed cycle detection3-color DFS / Kahn count12
Connect all at min costMST (Kruskal / Prim)13–14
Two-group split / conflicts apartBipartite check16
Directed mutual reachability / 2-SATTarjan's SCC17
Single points of failure (undirected)Bridges / articulation18
Goal-directed search / heuristicA*19
Use every edge once / itineraryEulerian (Hierholzer)19
Matching / min cut / capacity limitsMax flow20

🎯 Capstone Review (~80 min)

You've covered all 6 levels. The differentiator now isn't knowing more algorithms — it's recognizing which one a disguised problem needs and coding it cleanly under pressure. Drill the recognition table until it's reflexive.

📚 References