← Back to Tutorials Chapter 10

Maximum Flow in Networks

A flow network is a directed graph where each edge has a capacity (the maximum amount of flow it can carry). The goal is to find the maximum amount of flow that can be sent from a source vertex (s) to a sink vertex (t) while respecting all capacity constraints.

Flow networks model real-world problems like water pipelines, data traffic in computer networks, airline scheduling, and even bipartite matching.
Maximum flow network

Flow Network Terminology

Ford-Fulkerson Method

The Ford-Fulkerson method is a greedy iterative algorithm. It repeatedly finds an augmenting path from s to t in the residual graph and pushes flow along that path. The process repeats until no more augmenting paths exist.

Residual Graph

The residual graph Gf shows the remaining capacity on each edge after some flow has been sent. For each original edge (u, v) with capacity c and flow f, the residual graph contains:

def ford_fulkerson(graph, source, sink):
    n = len(graph)
    # Residual graph: res[u][v] = remaining capacity
    res = [row[:] for row in graph]
    max_flow = 0

    def bfs(s, t, parent):
        visited = [False] * n
        queue = [s]
        visited[s] = True
        while queue:
            u = queue.pop(0)
            for v in range(n):
                if not visited[v] and res[u][v] > 0:
                    parent[v] = u
                    visited[v] = True
                    queue.append(v)
                    if v == t:
                        return True
        return False

    parent = [-1] * n
    while bfs(source, sink, parent):
        # Find the bottleneck capacity along the augmenting path
        bottleneck = float('inf')
        v = sink
        while v != source:
            u = parent[v]
            bottleneck = min(bottleneck, res[u][v])
            v = u
        # Update residual capacities
        v = sink
        while v != source:
            u = parent[v]
            res[u][v] -= bottleneck
            res[v][u] += bottleneck
            v = u
        max_flow += bottleneck
    return max_flow

Edmonds-Karp Algorithm

Edmonds-Karp is a specific implementation of Ford-Fulkerson that uses BFS to find the shortest augmenting path (in terms of number of edges). This guarantees O(V * E²) time complexity, whereas a naive DFS-based Ford-Fulkerson can be exponential.

The key insight: BFS finds the path with the fewest edges, which bounds the number of augmentations to O(V * E). Each BFS costs O(E), yielding O(V * E²) overall.

Max-Flow Min-Cut Theorem

One of the most important results in network flow theory:

The value of the maximum flow from s to t equals the capacity of the minimum s-t cut.

An s-t cut is a partition of vertices into two sets S and T (with s in S and t in T such that the sum of capacities of edges from S to T is minimized). The minimum cut is the bottleneck of the network.

In the residual graph after max flow is computed, the set of vertices reachable from s forms the minimum cut. Edges crossing from S (reachable) to T (unreachable) are the bottleneck edges.

Applications of Maximum Flow

# Bipartite matching via max flow
def max_bipartite_matching(left, right, edges):
    # Build flow network:
    # source = 0, left = 1..|left|, right = |left|+1..|left|+|right|, sink = last
    n = 2 + len(left) + len(right)
    graph = [[0]*n for _ in range(n)]
    source, sink = 0, n - 1
    for i in range(len(left)):
        graph[source][1 + i] = 1
    for i in range(len(right)):
        graph[1 + len(left) + i][sink] = 1
    for u, v in edges:
        graph[1 + u][1 + len(left) + v] = 1
    return ford_fulkerson(graph, source, sink)

Complexity Summary

AlgorithmTime ComplexityNotes
Ford-Fulkerson (DFS)O(E * |f|)Depends on max flow value; can be slow
Edmonds-Karp (BFS)O(V * E²)Polynomial; guarantees termination
Dinic'sO(V² * E)Faster for unit-capacity graphs; O(E * sqrt(V)) for bipartite matching

Practice Task

Given a flow network with 5 nodes (source=0, sink=4) and the following capacities:

graph = [
    [0, 16, 13, 0, 0],
    [0, 0, 10, 12, 0],
    [0, 4, 0, 0, 14],
    [0, 0, 9, 0, 20],
    [0, 0, 0, 0, 0]
]

Implement Edmonds-Karp to compute the max flow. Then find the min-cut edges by running BFS on the residual graph.