Algorithm Search⌘K

Proofs: Dinic's algorithm

These are the human proofs of Dinic's algorithm, at full length.

Dinic's algorithm runs in O(n^2 m) time full

This proof shows: time.worst.

Fix a run on a network with nn vertices and mm edges, and assume, as for every maximum flow bound stated in terms of mm, that m≥n−1m \ge n - 1 after removing the vertices that no edge touches; otherwise add O(n)O(n) to each bound. Each arithmetic operation and comparison costs O(1)O(1).

Theorem 1 (phases). There are at most nn runs of line L3. By Claim 5 of the correctness proof, df(t)d_f(t) grows by at least 1 in each phase, and it lies in {1,…,n−1}\{1, \dots, n - 1\} while the loop continues, so there are at most n−1n - 1 phases and one final search.

Theorem 2 (one phase costs O(nm)). Line L1 costs O(m)O(m) once. Line L3 is a breadth-first search over at most 2m2m arcs: O(n+m)O(n + m). Line L5 costs O(n)O(n). In the loop of lines L7 to L14:

  • lines L12 and L14 each move a pointer one arc forward, and there are 2m2m arcs, so they run at most 2m2m times in all, at O(1)O(1) each;
  • line L9 runs at most mm times (Claim 4 of the correctness proof) and costs O(∣P∣)=O(n)O(|P|) = O(n) each time, since ∣P∣=d(t)≤n−1|P| = d(t) \le n - 1;
  • line L11 adds an arc to PP, and each arc added to PP leaves it later by line L9 (at most n−1n - 1 arcs per run, already counted) or by line L14 (one arc per run). So line L11 runs at most (n−1)⋅m+2m(n - 1) \cdot m + 2m times;
  • line L13 runs once.

So the loop costs O(nm+m)=O(nm)O(nm + m) = O(nm), and one phase costs O(n+m+nm)=O(nm)O(n + m + nm) = O(nm).

Theorem 3 (total). By Theorems 1 and 2 the time is O(n⋅nm)=O(n2m)O(n \cdot nm) = O(n^2 m). The arrays cfc_f, the adjacency lists, level\text{level}, itit, the queue and PP take Θ(n+m)\Theta(n + m) space. Nothing in the count uses integrality, so the bound holds for real capacities. ■\blacksquare

Dinic's algorithm returns a maximum flow and a minimum cut full

This proof shows: correctness, termination.

Let N=(G,c,s,t)N = (G, c, s, t) be a flow network with real capacities c(e)≥0c(e) \ge 0 and s≠ts \ne t. Write cfc_f for the residual capacities, f(e)=cf(e−)f(e) = c_f(e^-), GfG_f for the residual graph of arcs with cf>0c_f > 0, and d(v)d(v) for the value level[v]\text{level}[v] computed in line L3 of the current phase. The level graph LfL_f is the set of arcs (v,w)(v, w) with cf>0c_f > 0 and d(w)=d(v)+1d(w) = d(v) + 1; its arcs are tested with the residual capacities of the moment.

Claim 1 (each augmentation keeps a flow). When line L9 runs, PP is a walk from ss to u=tu = t built by line L11, so each arc of PP had cf>0c_f > 0 and goes up one level. The levels along PP are 0,1,…,d(t)0, 1, \dots, d(t), so PP is a simple path. Every arc of PP still has cf>0c_f > 0 at line L9: an arc of LfL_f loses residual capacity only through an augmentation, and an augmentation restarts the walk with PP empty. So Δ>0\Delta > 0, and by the invariant proved for Ford-Fulkerson (residual capacities stay nonnegative, cf(e+)+cf(e−)=c(e)c_f(e^+) + c_f(e^-) = c(e), conservation holds) ff stays an s-t flow and its value grows by Δ\Delta.

Claim 2 (level arcs only shrink in a phase). An augmentation adds residual capacity only to reverses (w,v)(w, v) of arcs (v,w)(v, w) of LfL_f, which have d(v)=d(w)−1d(v) = d(w) - 1, so they are not level arcs. The levels dd are fixed during the phase. Hence the set of arcs of LfL_f with cf>0c_f > 0 only loses members during the phase.

Claim 3 (dead vertices are dead). Call uu dead when it[u]it[u] has run past the last arc of uu. Invariant: no dead vertex has a path to tt in LfL_f using arcs with cf>0c_f > 0, and every arc that a pointer has passed is either not a level arc, or has cf=0c_f = 0, or ends at a dead vertex. A pointer moves in line L12 only when the arc fails the test of line L10, that is, it is not a level arc or it has cf=0c_f = 0; by Claim 2 it stays so. A pointer moves in line L14 past the arc (v,u)(v, u) just after uu was found dead. Every arc of a dead uu has been passed, so each one is useless or ends at a dead vertex, and by induction on the order in which vertices die, uu has no path to tt with positive level arcs. The sink tt never dies, because line L8 runs before lines L10 to L14 whenever u=tu = t.

Claim 4 (each phase ends and finds a blocking flow). Each pass of the loop runs one of lines L9, L11, L12, L14. Lines L12 and L14 move a pointer, at most 2m2m times in all. Line L9 makes some arc of PP have cf=0c_f = 0, and by Claim 2 it stays so, so it is in no later PP; LfL_f has at most mm arcs, since the two arcs of one edge cannot both go up a level, so line L9 runs at most mm times. Line L11 runs at most d(t)≤n−1d(t) \le n - 1 times between two runs of lines L9 or L14, since each run raises the level of uu by 1. So the loop ends, and it ends only in line L13, with ss dead. By Claim 3, LfL_f then has no s-t path with all cf>0c_f > 0: the flow added in this phase is a blocking flow of the level graph of the phase start.

Claim 5 (termination). By the lemma on blocking flows, adding a blocking flow of LfL_f makes df(t)d_f(t) strictly larger. While the loop of line L2 continues, 1≤df(t)≤n−11 \le d_f(t) \le n - 1. So there are at most n−1n - 1 phases before line L4 leaves the loop.

Claim 6 (optimality). In the last run of line L3, tt is not reached, and S={v:d(v)≥0}S = \{v : d(v) \ge 0\} is exactly the set of vertices reachable from ss in GfG_f, with s∈Ss \in S and t∉St \notin S. Each edge (u,v)(u, v) with u∈Su \in S, v∉Sv \notin S has cf(e+)=0c_f(e^+) = 0, so f(e)=c(e)f(e) = c(e); each edge (v,u)(v, u) with v∉Sv \notin S, u∈Su \in S has cf(e−)=0c_f(e^-) = 0, so f(e)=0f(e) = 0. By conservation, ∣f∣=f(S,Sˉ)−f(Sˉ,S)=c(S,Sˉ)|f| = f(S, \bar S) - f(\bar S, S) = c(S, \bar S). Since every s-t flow gg has ∣g∣≤c(S,Sˉ)|g| \le c(S, \bar S) and every s-t cut XX has c(X,Xˉ)≥∣f∣c(X, \bar X) \ge |f|, the flow is maximum and the cut is minimum. ■\blacksquare

Back to Dinic's algorithm