Homeβ€Ί DSAβ€Ί Maximum Flow β€” Ford-Fulkerson and Edmonds-Karp Algorithm

Maximum Flow β€” Ford-Fulkerson and Edmonds-Karp Algorithm

Where developers are forged. Β· Structured learning Β· Free forever.
πŸ“ Part of: Graphs β†’ Topic 15 of 17
Learn the maximum flow problem, Ford-Fulkerson method, and Edmonds-Karp algorithm.
πŸ”₯ Advanced β€” solid DSA foundation required
In this tutorial, you'll learn:
  • Residual graph is the key data structure: for each edge (u,v) with capacity c and flow f, maintain forward edge (c-f) and backward edge (f). Backward edges enable flow cancellation.
  • Ford-Fulkerson framework: find any augmenting path from s to t in residual graph, push flow equal to bottleneck capacity. Repeat until no path exists.
  • Edmonds-Karp = Ford-Fulkerson with BFS for augmenting paths. BFS guarantees shortest paths, which bounds the number of augmentations to O(VE), giving O(VE^2) total.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
⚑ Quick Answer
Imagine a network of pipes with different capacities connecting a source to a sink. The maximum flow problem asks: how much water can flow from source to sink per second? Ford-Fulkerson repeatedly finds paths from source to sink and pushes flow along them until no more path exists. Edmonds-Karp is Ford-Fulkerson with BFS β€” always using the shortest augmenting path, which guarantees polynomial time.

Maximum flow is one of the most widely applicable algorithmic primitives in combinatorial optimisation. Bipartite matching reduces to max flow. Project selection with dependencies reduces to max flow. Image segmentation reduces to max flow. Network routing capacity planning reduces to max flow. If you see a problem involving 'maximum amount of something flowing through a constrained network', max flow is almost certainly the right tool.

Ford-Fulkerson (1956) established the foundational framework. Edmonds-Karp (1972) added the key insight: always augment along the shortest path (BFS) rather than any path. This single change moves the complexity from 'possibly exponential' to 'provably polynomial O(VE^2)' β€” and that guaranteed polynomiality is what makes the algorithm deployable in real systems.

Key Concepts

Flow network: Directed graph G=(V,E) with capacity c(u,v) β‰₯ 0 for each edge. Flow: f(u,v) satisfying: (1) capacity constraint: f(u,v) ≀ c(u,v), (2) flow conservation: inflow = outflow at all nodes except s and t. Residual graph: For each edge (u,v) with capacity c and flow f, add forward edge with residual c-f and backward edge with capacity f. Augmenting path: Any path from s to t in the residual graph. Max-flow min-cut theorem: Maximum flow = minimum cut capacity.

Ford-Fulkerson / Edmonds-Karp

Edmonds-Karp uses BFS to find shortest augmenting paths β€” guaranteeing O(VEΒ²).

edmonds_karp.py Β· PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
from collections import deque

def edmonds_karp(graph: dict, source: str, sink: str) -> int:
    """
    graph: {node: {neighbour: capacity}}
    Returns maximum flow from source to sink.
    """
    # Build residual graph
    residual = {u: dict(v_cap) for u, v_cap in graph.items()}
    for u in graph:
        for v in graph[u]:
            if v not in residual: residual[v] = {}
            if u not in residual[v]: residual[v][u] = 0

    def bfs_augmenting_path():
        visited = {source: None}
        queue = deque([source])
        while queue:
            node = queue.popleft()
            if node == sink: break
            for neighbour, cap in residual[node].items():
                if neighbour not in visited and cap > 0:
                    visited[neighbour] = node
                    queue.append(neighbour)
        if sink not in visited: return None, 0
        # Reconstruct path and find bottleneck
        path, node = [], sink
        while node != source:
            prev = visited[node]
            path.append((prev, node))
            node = prev
        bottleneck = min(residual[u][v] for u,v in path)
        return path, bottleneck

    max_flow = 0
    while True:
        path, bottleneck = bfs_augmenting_path()
        if path is None: break
        max_flow += bottleneck
        for u, v in path:
            residual[u][v] -= bottleneck
            residual[v][u] += bottleneck
    return max_flow

graph = {
    's': {'a': 10, 'b': 10},
    'a': {'t': 10, 'b': 2},
    'b': {'t': 10, 'a': 0},
    't': {}
}
print(edmonds_karp(graph, 's', 't'))  # 20
β–Ά Output
20

The Max-Flow Min-Cut Theorem

The maximum flow equals the capacity of the minimum cut (minimum total capacity of edges crossing from the source side to the sink side of any partition of V into S and T).

This duality is fundamental: finding max flow finds min cut, enabling applications like: - Network reliability: Minimum edges to remove to disconnect source from sink - Bipartite matching: Max matching = max flow (KΓΆnig's theorem) - Project selection: Which projects to take given dependencies

πŸ”₯
ApplicationsBipartite matching, airline crew scheduling, image segmentation, project selection (profitable projects with dependencies), baseball elimination β€” all reduce to maximum flow.

Complexity

Ford-Fulkerson with DFS: O(Ef) where f = max flow value β€” can be exponential Edmonds-Karp (BFS): O(VEΒ²) β€” polynomial always Dinic's algorithm: O(VΒ²E) β€” faster in practice

For most interview purposes, Edmonds-Karp is the expected answer.

🎯 Key Takeaways

  • Residual graph is the key data structure: for each edge (u,v) with capacity c and flow f, maintain forward edge (c-f) and backward edge (f). Backward edges enable flow cancellation.
  • Ford-Fulkerson framework: find any augmenting path from s to t in residual graph, push flow equal to bottleneck capacity. Repeat until no path exists.
  • Edmonds-Karp = Ford-Fulkerson with BFS for augmenting paths. BFS guarantees shortest paths, which bounds the number of augmentations to O(VE), giving O(VE^2) total.
  • Max-flow min-cut theorem: max flow = min cut capacity. The cut found implicitly is the 'bottleneck' of the network β€” removing it disconnects s from t at minimum cost.
  • Reductions: bipartite matching (unit capacity graph), project selection (source/sink with profit/cost edges), baseball elimination, image segmentation β€” all reduce to max flow.

Interview Questions on This Topic

  • QWhat is a residual graph and why are backward edges necessary?
  • QState and explain the max-flow min-cut theorem.
  • QWhy does Edmonds-Karp guarantee polynomial time while generic Ford-Fulkerson doesn't?
  • QHow would you model bipartite matching as a maximum flow problem?

Frequently Asked Questions

What is the difference between Ford-Fulkerson and Edmonds-Karp?

Ford-Fulkerson is the general method β€” find any augmenting path. Edmonds-Karp is Ford-Fulkerson with the specific choice of BFS for finding shortest (fewest edges) augmenting paths. This choice gives the O(VEΒ²) polynomial bound.

πŸ”₯
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousA* Search AlgorithmNext β†’Eulerian Path and Circuit β€” Hierholzer's Algorithm
Forged with πŸ”₯ at TheCodeForge.io β€” Where Developers Are Forged