ADVANCED ALGORITHMS - NETWORK FLOW:Network Flow Applications: Matching, Scheduling, Image Segmentation
Mastering network flow applications: matching, scheduling, image segmentation concepts and implementation.
Network Flow Applications
The power of network flow lies in its generality. Dozens of important problems reduce elegantly to max-flow or min-cost flow. Mastering this reduction technique is essential for competitive programming and system design.
1. Bipartite Matching
Problem: Given a bipartite graph G = (L ∪ R, E), find a maximum matching (no two edges share an endpoint).
Reduction:
- Add super-source S with edges to every left vertex (capacity 1)
- Add super-sink T with edges from every right vertex (capacity 1)
- Original edges get capacity 1
- Max flow = max matching
def max_bipartite_matching(left_size, right_size, edges):
"""
Maximum bipartite matching via max-flow (Dinic's in O(E * sqrt(V))).
Nodes: 0=source, 1..left_size=left, left_size+1..left+right=right, last=sink
"""
n = left_size + right_size + 2
source = 0
sink = n - 1
g = MaxFlowDinics(n)
# Source to all left vertices
for l in range(1, left_size + 1):
g.add_edge(source, l, 1)
# All right vertices to sink
for r in range(left_size + 1, left_size + right_size + 1):
g.add_edge(r, sink, 1)
# Original bipartite edges
for l, r in edges:
g.add_edge(l, left_size + r, 1)
return g.max_flow(source, sink)
# Hall's theorem: a bipartite graph has a perfect matching iff
# for every subset S of L, |N(S)| >= |S| (neighborhood is large enough)
König's Theorem: In bipartite graphs, maximum matching = minimum vertex cover. This connects flow (matching) to LP duality and the min-cut.
2. Edge-Disjoint Paths
Problem: Find the maximum number of paths from s to t that share no edges.
Reduction: Set all edge capacities to 1. Max flow = max number of edge-disjoint paths.
Vertex-disjoint paths: "Split" each vertex v into v_in and v_out with an edge of capacity 1 between them. Edges go into v_in and out of v_out.
def vertex_disjoint_paths(n, edges, source, sink):
"""
Maximum vertex-disjoint s-t paths via node-splitting.
2n nodes: node v becomes v_in (v) and v_out (v + n).
"""
g = MaxFlowDinics(2 * n)
# Internal edges: v_in → v_out with capacity 1 (except source/sink: use n)
for v in range(n):
cap = n if (v == source or v == sink) else 1
g.add_edge(v, v + n, cap)
# Original edges: u_out → v_in with capacity n (unlimited)
for u, v in edges:
g.add_edge(u + n, v, n)
g.add_edge(v + n, u, n) # undirected
return g.max_flow(source, sink + n)
3. Task Assignment with Capacity Constraints
Problem: Assign n jobs to m machines. Job j can run on machine i (given as a set of valid pairs). Each machine i can handle at most d[i] jobs simultaneously.
def job_assignment(n_jobs, n_machines, valid_pairs, machine_capacity):
"""
Maximum job assignment with machine capacity constraints.
Source → job (cap 1) → machine (cap 1) → sink (cap machine_capacity[m])
"""
source = 0
sink = n_jobs + n_machines + 1
g = MaxFlowDinics(sink + 1)
for j in range(n_jobs):
g.add_edge(source, j + 1, 1)
for m in range(n_machines):
g.add_edge(n_jobs + 1 + m, sink, machine_capacity[m])
for j, m in valid_pairs:
g.add_edge(j + 1, n_jobs + 1 + m, 1)
return g.max_flow(source, sink)
4. Project Selection (Profit Maximization)
Problem: n projects with profits p[i] (can be negative). m resources with costs c[j]. Project i requires resource j (edges). Select projects to maximize net profit.
Reduction (project selection / closure problem):
- Source S → project i with capacity p[i] if p[i] > 0
- Project i → sink T with capacity −p[i] if p[i] < 0
- Resource j → sink T with capacity c[j]
- Project i → resource j (dependency) with capacity ∞
Max profit = Σ max(0, p[i]) − min_cut(S, T)
5. Circulation with Demands
Problem: Each edge has both lower bound l(e) and upper bound c(e) on flow. Does a feasible circulation exist?
Reduction:
- For each edge (u, v, l, c): add edge (u, v, c − l) to new graph
- Add super-source S and super-sink T
- For each node v: let excess = Σ l(in-edges) − Σ l(out-edges)
- If excess > 0: add edge (S, v, excess)
- If excess < 0: add edge (v, T, −excess)
- A feasible circulation exists ↔ max flow from S to T saturates all edges from S
Identifying Network Flow Problems
A problem likely reduces to network flow if it involves:
- Routing or matching between two "sides"
- Capacities on edges or nodes
- Maximum/minimum over a sum or count
- Conservation constraints (flow in = flow out)
- Cuts separating source from sink
Practice Problems
- Solve a task-scheduling problem where nurses must be assigned to shifts with hospital capacity constraints
- Find max-flow in a network and extract the actual matching (not just the count)
- Given a bipartite graph, find both a maximum matching AND the minimum vertex cover (König's theorem)
- Design a flow network to solve "at least k edge-disjoint paths exist" as a decision problem
- Model the "project selection" problem and solve on a small example