Logo
Published on

Network Flows - Part 5

Authors
  • avatar
    Name
    Till Heller
    Twitter

So far in this series, we've built up the theory of network flows — definitions, the Max-Flow Min-Cut Theorem, and efficient algorithms. Now comes the payoff. Maximum flow is not just a problem in its own right; it's a tool for solving a surprising variety of other problems. In this part, we'll see three applications that look very different on the surface but all reduce to finding a maximum flow in a cleverly constructed network.

Bipartite Matching

Our first application connects directly to the Introduction to Graph Theory series. In Part 8 of that series, we studied matchings in bipartite graphs — pairing up vertices from two groups so that no vertex is used twice. It turns out that finding a maximum matching in a bipartite graph is equivalent to finding a maximum flow in a specific network.

Given a bipartite graph G=(AB,E)G = (A \cup B, E), we construct a flow network NN as follows:

  1. Create a source ss and a sink tt.
  2. For each vertex aAa \in A, add an arc (s,a)(s, a) with capacity 11.
  3. For each edge (a,b)E(a, b) \in E with aAa \in A and bBb \in B, add an arc (a,b)(a, b) with capacity 11.
  4. For each vertex bBb \in B, add an arc (b,t)(b, t) with capacity 11.

Every arc has capacity 11, so by the Integrality Theorem (Theorem 2 from Part 3), there exists a maximum flow that is integer-valued — meaning each arc carries either 00 or 11 unit of flow.

bipartite-flow

Theorem 4. The value of a maximum flow in NN equals the size of a maximum matching in GG.

Proof. We show a bijection between integer flows and matchings.

Given an integer flow ff in NN, consider the set M={(a,b):aA,bB,f(a,b)=1}M = \{(a,b) : a \in A, b \in B, f(a,b) = 1\}. We claim MM is a matching. For any aAa \in A, at most 11 unit of flow enters aa (since c(s,a)=1c(s,a) = 1), so at most one arc from aa to BB carries flow — meaning aa appears in at most one edge of MM. Similarly, for any bBb \in B, at most 11 unit leaves through (b,t)(b,t), so bb appears in at most one edge. Thus MM is a valid matching of size f|f|.

Conversely, given a matching MM in GG, define a flow by setting f(s,a)=f(a,b)=f(b,t)=1f(s,a) = f(a,b) = f(b,t) = 1 for each edge (a,b)M(a,b) \in M and 00 everywhere else. This is a valid flow of value M|M|: capacity constraints are satisfied (all capacities are 11), and flow conservation holds at every intermediate vertex.

Since larger flows correspond to larger matchings and vice versa, maximizing one is equivalent to maximizing the other.

Let's try a small example. Consider the bipartite graph with A={a1,a2,a3}A = \{a_1, a_2, a_3\}, B={b1,b2}B = \{b_1, b_2\}, and edges {(a1,b1),(a1,b2),(a2,b1),(a3,b2)}\{(a_1, b_1), (a_1, b_2), (a_2, b_1), (a_3, b_2)\}. The flow network adds ss connected to all of AA and tt connected from all of BB, all with capacity 11. Running Edmonds-Karp on this network finds a maximum flow of value 22, corresponding to the matching {(a1,b1),(a3,b2)}\{(a_1, b_1), (a_3, b_2)\} (or equivalently {(a2,b1),(a1,b2)}\{(a_2, b_1), (a_1, b_2)\}). Since B=2|B| = 2, we cannot match all three vertices in AA — and indeed Hall's condition fails for S=AS = A: N(A)=2<3=A|N(A)| = 2 < 3 = |A|.

This reduction also gives us a new proof of König's theorem (Theorem 12 from the graph theory series). The minimum cut in NN corresponds to a minimum vertex cover in GG, so König's equality ν(G)=τ(G)\nu(G) = \tau(G) follows directly from the Max-Flow Min-Cut Theorem1.

Edge-Disjoint Paths

Our second application answers a natural question about connectivity: how many "independent" routes exist between two vertices? More precisely, given a directed graph D=(V,A)D = (V, A) and two vertices ss and tt, how many paths from ss to tt can we find that share no arcs?

Definition 11. Two ss-tt-paths are edge-disjoint (or arc-disjoint in digraphs) if they share no arc.

edge-disjoint

The connection to flows is immediate: treat the digraph as a flow network with capacity 11 on every arc. An integer flow of value kk decomposes into kk unit-flow paths from ss to tt, and since each arc has capacity 11, these paths are arc-disjoint.

Theorem 5 (Menger, 1927). In a directed graph, the maximum number of arc-disjoint ss-tt-paths equals the minimum number of arcs whose removal disconnects tt from ss.

Proof. This is a direct consequence of the Max-Flow Min-Cut Theorem applied to the network with unit capacities. The maximum flow value equals the maximum number of arc-disjoint paths (by integrality and flow decomposition). The minimum cut capacity equals the minimum number of arcs that must be removed to separate ss from tt (since each arc has capacity 11, the cut capacity is just the number of arcs crossing the cut). By max-flow min-cut, these two quantities are equal.

Menger's theorem predates the Max-Flow Min-Cut Theorem by nearly three decades — Menger proved it in 1927, while Ford and Fulkerson's theorem came in 1956. In a sense, Menger's theorem was a precursor that hinted at the deeper duality between flows and cuts.

There is also a vertex-disjoint version: two paths are vertex-disjoint if they share no internal vertex (they may share ss and tt).

Theorem 6 (Menger, vertex version). The maximum number of internally vertex-disjoint ss-tt-paths equals the minimum number of vertices (other than ss and tt) whose removal disconnects tt from ss.

This can also be proved via max-flow, using a standard trick: replace each vertex vv (other than ss and tt) with two copies vinv_{in} and voutv_{out} connected by an arc (vin,vout)(v_{in}, v_{out}) of capacity 11. All arcs originally entering vv now enter vinv_{in}, and all arcs originally leaving vv now leave from voutv_{out}. The capacity-11 arc between the copies ensures that at most one path passes through vv, effectively enforcing vertex-disjointness.

Project Selection

Our third application comes from optimization and has a very different flavor. Imagine a company evaluating a set of potential projects. Each project has a profit (which may be positive or negative — some projects are investments that cost money). Some projects depend on others: if you undertake project ii, you must also undertake project jj. The goal is to select a subset of projects that maximizes total profit while respecting all dependencies.

Formally, we have a set of projects P={1,2,,n}P = \{1, 2, \ldots, n\} with profits piRp_i \in \mathbb{R}, and a set of dependencies — pairs (i,j)(i, j) meaning "if project ii is selected, then project jj must also be selected." We want to find a subset SPS \subseteq P such that SS is closed (if iSi \in S and (i,j)(i,j) is a dependency, then jSj \in S) and iSpi\sum_{i \in S} p_i is maximized.

This is the project selection problem (also called the closure problem), and it can be solved by a maximum flow computation.

We construct the following flow network:

  1. Create a source ss and a sink tt.
  2. For each project ii with pi>0p_i > 0, add an arc (s,i)(s, i) with capacity pip_i.
  3. For each project ii with pi<0p_i < 0, add an arc (i,t)(i, t) with capacity pi|p_i|.
  4. For each dependency (i,j)(i, j), add an arc (i,j)(i, j) with capacity \infty.

The infinite capacities on dependency arcs ensure that they are never part of a minimum cut — cutting them would give infinite capacity. A finite minimum cut (S,T)(S, T) with sSs \in S and tTt \in T corresponds to a closed set: the selected projects are S{s}S \setminus \{s\}.

project-selection

Theorem 7. The maximum profit of a closed set equals i:pi>0pif\sum_{i: p_i > 0} p_i - |f^*|, where f|f^*| is the maximum flow value (equivalently, the minimum cut capacity).

The intuition is as follows. Start by tentatively selecting all profitable projects — this gives profit i:pi>0pi\sum_{i: p_i > 0} p_i. The minimum cut tells us the "cost" of making the selection feasible: we either give up some profitable projects (cutting their arcs from ss) or include some unprofitable ones (cutting their arcs to tt). The minimum cut minimizes this total cost, and what remains is the optimal profit.

Consider a small example with four projects: p1=5p_1 = 5, p2=3p_2 = -3, p3=4p_3 = 4, p4=1p_4 = -1, and dependencies (1,2)(1, 2) and (3,4)(3, 4). Project 11 yields profit 55 but requires project 22 (which costs 33), and project 33 yields 44 but requires project 44 (which costs 11).

The flow network has arcs (s,1)(s,1) with capacity 55, (s,3)(s,3) with capacity 44, (2,t)(2,t) with capacity 33, (4,t)(4,t) with capacity 11, (1,2)(1,2) with capacity \infty, and (3,4)(3,4) with capacity \infty. The minimum cut turns out to have capacity 44: we cut (2,t)(2,t) and (4,t)(4,t), meaning we include all four projects. The maximum profit is (5+4)4=5(5 + 4) - 4 = 5, which matches p1+p2+p3+p4=53+41=5p_1 + p_2 + p_3 + p_4 = 5 - 3 + 4 - 1 = 5. Selecting all projects is optimal because the profitable ones outweigh the costs of their dependencies2.

The Power of Reductions

The three applications in this part illustrate a general principle: many combinatorial optimization problems can be reduced to maximum flow. The art lies in designing the right network — choosing the vertices, arcs, and capacities so that the max-flow min-cut structure captures the problem's constraints and objectives.

This is one of the reasons network flow theory occupies such a central place in optimization: not because flow problems themselves are so common, but because so many other problems can be expressed as flow problems and solved with the same efficient algorithms.

Looking Ahead

We've seen that maximum flow is a versatile tool, but it optimizes only one thing: the total amount of flow. What if we also care about cost — for example, different routes have different shipping costs, and we want to maximize flow at minimum expense? In the next part, we'll introduce the minimum-cost flow problem, which adds a cost dimension to our networks and opens up an even richer set of applications.

Footnotes

  1. To see this, note that every ss-tt-cut in NN with capacity kk corresponds to choosing kk vertices from ABA \cup B that cover all edges. The unit capacities ensure that the minimum cut picks individual arcs — each arc (s,a)(s,a) or (b,t)(b,t) in the cut corresponds to including aa or bb in the vertex cover.

  2. If instead p2=8p_2 = -8, then the dependency of project 11 on project 22 would make selecting project 11 unprofitable overall (58=35 - 8 = -3). The minimum cut would cut (s,1)(s, 1) with capacity 55, meaning we give up project 11. The optimal selection would be {3,4}\{3, 4\} with profit 41=34 - 1 = 3.