Hubbry Logo
Dinic's algorithmDinic's algorithmMain
Open search
Dinic's algorithm
Community hub
Dinic's algorithm
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Dinic's algorithm
Dinic's algorithm
from Wikipedia

Dinic's algorithm or Dinitz's algorithm is a strongly polynomial algorithm for computing the maximum flow in a flow network, conceived in 1970 by Israeli (formerly Soviet) computer scientist Yefim Dinitz.[1] The algorithm runs in time and is similar to the Edmonds–Karp algorithm, which runs in time, in that it uses shortest augmenting paths. The introduction of the concepts of the level graph and blocking flow enable Dinic's algorithm to achieve its performance.

History

[edit]

Dinitz invented the algorithm in January 1969, as a master's student in Georgy Adelson-Velsky's group. A few decades later, he would recall:[2]

In Adel'son-Vel'sky's Algorithms class, the lecturer had a habit of giving the problem to be discussed at the next meeting as an exercise to students. The DA was invented in response to such an exercise. At that time, the author was not aware of the basic facts regarding [the Ford–Fulkerson algorithm]….

⋮ Ignorance sometimes has its merits. Very probably, DA would not have been invented then, if the idea of possible saturated edge desaturation had been known to the author.

In 1970, Dinitz published a description of the algorithm in Doklady Akademii Nauk SSSR. In 1974, Shimon Even and (his then Ph.D. student) Alon Itai at the Technion in Haifa were very curious and intrigued by Dinitz's algorithm as well as Alexander V. Karzanov's related idea of blocking flow. However it was hard for them to decipher these two papers, each being limited to four pages to meet the restrictions of journal Doklady Akademii Nauk SSSR. Even did not give up, and after three days of effort managed to understand both papers except for the layered network maintenance issue. Over the next couple of years, Even gave lectures on "Dinic's algorithm", mispronouncing the name of the author while popularizing it. Even and Itai also contributed to this algorithm by combining BFS and DFS, which is how the algorithm is now commonly presented.[2]

For about 10 years of time after the Ford–Fulkerson algorithm was invented, it was unknown if it could be made to terminate in polynomial time in the general case of irrational edge capacities. This caused a lack of any known polynomial-time algorithm to solve the max flow problem in generic cases. Dinitz's algorithm and the Edmonds–Karp algorithm (published in 1972) both independently showed that in the Ford–Fulkerson algorithm, if each augmenting path is the shortest one, then the length of the augmenting paths is non-decreasing and the algorithm always terminates.

Definition

[edit]

Let be a network with and the capacity and the flow of the edge , respectively.

The residual capacity is a mapping defined as,
  1. if ,
  2. if ,
  3. otherwise.
The residual graph is an unweighted graph , where
.
An augmenting path is an path in the residual graph .
Define to be the length of the shortest path from to in . Then the level graph of is the graph , where
.
A blocking flow is an flow such that the graph with contains no path. [Note 1][3]

Algorithm

[edit]

Dinic's Algorithm

Input: A network .
Output: An flow of maximum value.
  1. Set for each .
  2. Construct from of . If , stop and output .
  3. Find a blocking flow in .
  4. Augment flow by and go back to step 2.

Analysis

[edit]

It can be shown that the number of layers in each blocking flow increases by at least 1 each time and thus there are at most blocking flows in the algorithm. For each of them:

  • the level graph can be constructed by breadth-first search in time
  • a blocking flow in the level graph can be found in time[Note 2]

with total running time for each layer. As a consequence, the running time of Dinic's algorithm is .[2]

Using a data structure called dynamic trees, the running time of finding a blocking flow in each phase can be reduced to and therefore the running time of Dinic's algorithm can be improved to .

Special cases

[edit]

In networks with unit capacities, a much stronger time bound holds. Each blocking flow can be found in time, and it can be shown that the number of phases does not exceed and .[Note 3] Thus the algorithm runs in time.[4]

In networks that arise from the bipartite matching problem, the number of phases is bounded by , therefore leading to the time bound. The resulting algorithm is also known as Hopcroft–Karp algorithm. More generally, this bound holds for any unit network — a network in which each vertex, except for source and sink, either has a single entering edge of capacity one, or a single outgoing edge of capacity one, and all other capacities are arbitrary integers.[3]

Example

[edit]

The following is a simulation of Dinic's algorithm. In the level graph , the vertices with labels in red are the values . The paths in blue form a blocking flow.

1.

The blocking flow consists of

  1. with 4 units of flow,
  2. with 6 units of flow, and
  3. with 4 units of flow.

Therefore, the blocking flow is of 14 units and the value of flow is 14. Note that each augmenting path in the blocking flow has 3 edges.

2.

The blocking flow consists of

  1. with 5 units of flow.

Therefore, the blocking flow is of 5 units and the value of flow is 14 + 5 = 19. Note that each augmenting path has 4 edges.

3.

Since cannot be reached in , the algorithm terminates and returns a flow with maximum value of 19. Note that in each blocking flow, the number of edges in the augmenting path increases by at least 1.

See also

[edit]

Notes

[edit]

References

[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Dinic's algorithm (also known as Dinitz's algorithm) is a strongly polynomial-time algorithm for computing the maximum flow in a capacitated, directed from a source vertex to a sink vertex. Developed by Soviet mathematician Yefim A. Dinic and published in 1970, it addresses the by iteratively constructing a level graph—a layered subgraph of the residual network based on shortest-path distances from the source—and then finding a blocking flow that saturates all paths in this level graph before advancing to the next phase. The algorithm begins with zero flow and uses (BFS) to build the level graph in each phase, assigning levels to vertices based on the minimum distance from the source in the residual network. It then employs (DFS) on this level graph, restricted to edges that connect consecutive levels (admissible edges), to push as much flow as possible through multiple augmenting paths simultaneously until no more augmentations are feasible within the current layering. This phase-based approach ensures that the shortest augmenting path length strictly increases with each phase, bounding the number of phases to at most VV, where VV is the number of vertices. In terms of time complexity, Dinic's algorithm achieves O(V2E)O(V^2 E) time for general networks with VV vertices and EE edges, where each phase requires O(E)O(E) time for BFS and O(VE)O(VE) time for finding the blocking flow via DFS traversals. For unit-capacity networks, it runs in O(min(V2/3,E1/2)E)O(\min(V^{2/3}, E^{1/2}) E) time, making it particularly efficient for dense graphs or those with small capacities. Subsequent improvements, such as those incorporating dynamic trees by Sleator and Tarjan in 1980, reduce the general complexity to O(VElogV)O(V E \log V). Dinic's algorithm is notable for its modularity, which has inspired variants like the push-relabel method and its application in solving related problems, such as bipartite matching via flow reduction. It remains a cornerstone in network flow theory due to its balance of theoretical guarantees and practical performance, outperforming earlier augmenting-path algorithms like Edmonds-Karp in worst-case scenarios.

Background

Maximum Flow Problem

The maximum flow problem seeks to determine the maximum rate at which some commodity can be sent from a source vertex to a vertex in a , subject to capacity constraints on the edges. This problem models scenarios such as transporting goods through a transportation network or routing data in communication systems, where the goal is to maximize the total throughput without violating edge limits. Central to the problem are two distinguished vertices: the source ss, from which flow originates, and the tt, at which flow arrives. The value of a flow, denoted f|f|, is defined as the total outflow from ss (equivalently, the total inflow to tt), representing the net amount of commodity transferred. A valid flow must satisfy two key constraints: for every edge from vertex uu to vv, the flow f(u,v)f(u,v) cannot exceed the edge's capacity c(u,v)c(u,v); and at every intermediate vertex (neither ss nor tt), the total incoming flow equals the total outgoing flow, ensuring conservation of the commodity. Formally, given a G=(V,E)G = (V, E) with vertex set VV and edge set EE, the capacity function is c:V×VR+c: V \times V \to \mathbb{R}^+, where c(u,v)=0c(u,v) = 0 if no edge exists from uu to vv, and the flow function is f:V×VR+f: V \times V \to \mathbb{R}^+, satisfying 0f(u,v)c(u,v)0 \leq f(u,v) \leq c(u,v) for all u,vVu, v \in V. The is to find a flow ff that maximizes f=vVf(s,v)|f| = \sum_{v \in V} f(s,v) while adhering to these capacity and conservation constraints. This formulation originates from the work of Ford and Fulkerson, who introduced the problem in their seminal 1956 paper on maximal flows in networks.

Flow Networks

A flow network is formally defined as a directed graph G=(V,E)G = (V, E), where VV is the of vertices and EV×VE \subseteq V \times V is the set of directed edges, equipped with a capacity function c:ER0c: E \to \mathbb{R}_{\geq 0} that assigns a nonnegative c(e)c(e) to each edge eEe \in E, representing the maximum amount of flow that can traverse that edge. This structure models scenarios where commodities or resources are transported from origins to destinations through interconnected nodes subject to edge-specific limits. The network designates two distinguished vertices: the source sVs \in V, characterized by having no incoming flow (i.e., the net flow into ss is zero), and the sink tVt \in V, characterized by having no outgoing flow (i.e., the net flow out of tt is zero). These vertices serve as the starting point for flow injection and the endpoint for flow extraction, respectively, with all other vertices vV{s,t}v \in V \setminus \{s, t\} adhering to flow conservation. A flow f:ERf: E \to \mathbb{R} in the network assigns a real value to each edge, interpreted as the rate of flow along that edge. An admissible flow ff is one that satisfies two key properties: (i) the capacity constraint, requiring 0f(e)c(e)0 \leq f(e) \leq c(e) for every edge eEe \in E, ensuring no edge exceeds its limit or carries negative flow; and (ii) the conservation of flow, requiring that for every vertex vV{s,t}v \in V \setminus \{s, t\}, the total incoming flow equals the total outgoing flow, formally u:(u,v)Ef(u,v)=w:(v,w)Ef(v,w)\sum_{u: (u,v) \in E} f(u,v) = \sum_{w: (v,w) \in E} f(v,w). The value of such a flow is the net amount leaving the source (or equivalently, entering the sink), given by f=w:(s,w)Ef(s,w)|f| = \sum_{w: (s,w) \in E} f(s,w). Central to analyzing and augmenting flows is the residual graph Gf=(V,Ef)G_f = (V, E_f), derived from GG with respect to a given admissible flow ff, where Ef={(u,v)V×Vcf(u,v)>0}E_f = \{(u,v) \in V \times V \mid c_f(u,v) > 0\} and the residual capacity is defined as cf(u,v)=c(u,v)f(u,v)+f(v,u)c_f(u,v) = c(u,v) - f(u,v) + f(v,u) for all u,vVu, v \in V. This formulation accounts for potential flow reversals: if flow has been sent from uu to vv, the term +f(v,u)+f(v,u) (which equals the backward flow component) enables "undoing" part of that flow by adding a residual edge from vv to uu, effectively adjusting the net flow without violating capacities. The residual graph thus captures the remaining potential for increasing the overall flow from ss to tt. This framework underpins the , which aims to find an admissible flow of maximum value in .

Origins

Dinic's algorithm was invented by the Soviet mathematician Yefim A. Dinic in 1970. The algorithm was first published in Russian as "Algoritm resheniya zadachi o maksimal'ном potoke v seti s ocenkoj stepeni" in Doklady Akademii Nauk SSSR, volume 191, number 1, pages 49–52, and later translated into English as "Algorithm for Solution of a Problem of Maximum Flow in a Network with Power Estimates" in Soviet Mathematics Doklady, volume 11, pages 1277–1280. The development occurred amid growing interest in efficient algorithms for the in flow networks, a fundamental challenge in . Dinic's work was motivated by limitations in the Ford–Fulkerson method, introduced in 1956, which relies on augmenting paths but lacks a guaranteed polynomial-time bound in the worst case, potentially leading to exponential running times on certain inputs. To address this, Dinic incorporated to build layered structures in the residual graph, allowing for the efficient identification and saturation of multiple paths simultaneously through blocking flow computations. This innovation built upon emerging ideas for refining path selection in flow algorithms, particularly the use of BFS to prioritize shortest augmenting paths, a concept that would be independently formalized shortly thereafter in the of 1972. By providing a strongly of O(V²E)—where V is the number of vertices and E the number of edges—Dinic's algorithm marked a significant advancement, establishing a reliable bound independent of edge capacities and influencing subsequent research in network flows.

Developments and Influences

Following the publication of the original Russian paper in 1970, an English translation by R. F. Rinehart appeared in the same year in Soviet Mathematics Doklady, facilitating its wider dissemination and adoption in Western academic and research communities. This translation, along with analyses in subsequent works, helped bridge the gap for non-Russian speakers, leading to rapid integration into the study of network flows. Dinic's algorithm significantly influenced subsequent maximum flow research, particularly through its layered (level graph) approach, which inspired similar hierarchical structures in later algorithms. For instance, the push-relabel algorithm developed by Goldberg and Tarjan in 1988 explicitly builds on layering ideas from Dinic and Karzanov, using dynamic distance labels to guide flow augmentation in a manner analogous to level graphs. Additionally, Even and Tarjan's 1975 paper analyzed and extended Dinic's method for unit-capacity networks, demonstrating its O(\sqrt{n} m) time bound for bipartite matching and establishing it as a foundational technique for connectivity testing in graphs. Key refinements in the 1980s enhanced the efficiency of blocking flow computations in Dinic's framework. Cherkassky's 1983 algorithm improved the to O(V^2 E^{1/2}) for certain networks by using advanced data structures for path finding in level graphs. Independently, Galil and Tarjan's 1984 variant provided a simplified approach to computing blocking flows, maintaining the original O(VE) time per phase. Further advancements incorporated dynamic trees by Sleator and Tarjan in 1983, reducing the overall complexity to O(VE \log V). By the 1980s, Dinic's algorithm had become a standard topic in literature, appearing in key texts on network flows and graph algorithms due to its strong polynomial-time guarantees and practical performance. It also found implementation in established software libraries, such as LEDA, which incorporates a Galil-Naamad variant of Dinic's method for robust maximum flow computations.

Algorithm Description

Level Graph Construction

In Dinic's algorithm, the level graph construction serves as a preprocessing step in each phase to organize the residual graph into layers based on shortest path distances from the source, facilitating efficient discovery of multiple augmenting paths. This process begins with a (BFS) initiated from the source vertex ss in the current residual graph GfG_f, where edges with positive residual capacity are considered. The BFS assigns a level l(v)l(v) to each vertex vv, defined as the shortest path distance from ss to vv in GfG_f, with l(s)=0l(s) = 0. Vertices unreachable from ss receive infinite levels, and the search terminates if the tt is unreachable, indicating that the maximum flow has been achieved. Each such BFS traversal requires O(V+E)O(|V| + |E|) time, where V|V| is the number of vertices and E|E| is the number of edges in the graph. The level graph, denoted GflG_f^l, is then derived as a subgraph of GfG_f consisting solely of edges (u,v)(u, v) where l(v)=l(u)+1l(v) = l(u) + 1 and the residual capacity is positive. This restriction ensures that all paths in GflG_f^l from ss to tt are of minimal length in the original residual graph and that the graph is acyclic, as levels strictly increase along any path. By confining edges to those spanning exactly one level, the level graph directs flow strictly forward through successive layers, preventing cycles and backtracking during subsequent path-finding operations. This layering mechanism is repeated in multiple phases until no augmenting path exists to tt, with each phase updating the residual graph after computing a blocking flow in the current level graph. The level graph's structure partitions the network into ordered layers, enabling the algorithm to explore and saturate multiple disjoint shortest paths in parallel, which enhances efficiency over path-by-path augmentation methods.

Blocking Flow Computation

In Dinic's algorithm, the blocking flow computation occurs within the level graph, a directed acyclic subgraph of the residual graph consisting of edges that connect vertices at consecutive levels. A blocking flow in this graph is a feasible flow such that no augmenting path exists from the source ss to the tt relative to it, meaning every possible path from ss to tt in the level graph contains at least one saturated edge from this flow. The computation proceeds via repeated depth-first searches (DFS) initiated from the source ss, traversing only level-increasing edges to identify and saturate paths to tt. In each DFS, flow is pushed along the discovered path up to the minimum residual capacity of its edges, after which the path is updated in the residual graph by reducing capacities forward and adding backward edges. To efficiently explore multiple paths, the DFS maintains a through parent pointers, which link each visited vertex to its predecessor in the search . When a path reaches tt, augmentation occurs, and the search backtracks; if a subtree rooted at a vertex becomes blocked (no unsaturated outgoing edges lead to a viable path to tt), the algorithm advances to the next unexplored child edge from that vertex, continuing the search until all branches are exhausted. This iterative DFS process terminates when no further path from ss can reach tt in the current level graph, ensuring the blocking flow saturates all possible shortest augmenting paths. Multiple DFS calls per phase collectively find a maximal set of edge-disjoint paths, fully blocking the level graph without requiring exhaustive enumeration.

Procedure and Implementation

Overall Steps

Dinic's algorithm initializes the flow to zero on all edges of the given flow network, starting with an empty residual graph based on the initial capacities. The algorithm proceeds in a series of phases within a main loop. In each phase, it first constructs a level graph of the current residual graph using breadth-first search (BFS) from the source vertex ss, where each vertex is assigned a level corresponding to the length of the shortest path from ss to that vertex; this level graph includes only edges that connect vertices whose levels differ by exactly one. If the BFS does not reach the sink vertex tt, the algorithm terminates, as no augmenting path exists, and the current total flow is the maximum flow value. Otherwise, it computes a blocking flow in the level graph—a maximal flow that saturates every path from ss to tt in this graph—using depth-first search traversals as a subroutine. This blocking flow is then added to the overall flow, and the residual capacities are updated by adjusting the forward and backward edges accordingly. Each phase advances the flow by saturating all shortest augmenting paths in the current residual graph, ensuring progress toward the maximum flow. The process repeats with a new level graph until termination. The number of such phases is at most V1|V| - 1, where V|V| is the number of vertices, because the shortest path lengths from ss to unsaturated vertices strictly increase with each phase.

Data Structures and Pseudocode

Dinic's algorithm requires specific data structures to efficiently represent the and manage the residual capacities during execution. The graph is typically stored using , where each vertex maintains a list of outgoing edges in both the original network and the residual graph. Each edge structure includes fields for the target vertex, capacity, current flow, and a to the reverse edge to enable quick updates when augmenting paths are found. A level array, denoted as l[]l[], stores the shortest path distances from the source to each vertex in the current level graph. Additionally, an of iterators or current pointers (often called ptr[]ptr[] or similar) tracks the advancement position in each vertex's during DFS traversals, ensuring that previously explored edges are not revisited in the same blocking flow phase, which optimizes the search for multiple augmenting paths. When augmenting flow along a path, the residual graph is updated by reducing the residual capacity on forward edges and increasing it on corresponding reverse edges. For each forward edge from uu to vv with augmented flow f(u,v)f(u,v), the reverse from vv to uu receives an additional capacity of f(u,v)f(u,v), allowing for potential flow cancellation in future iterations. This bidirectional edge pairing is maintained in the adjacency lists from the outset, with reverse s initialized to zero capacity. The overall for these structures—adjacency lists for O(E)O(|E|) edges (including reverses, so O(2E)O(2|E|)), the level array for O(V)O(|V|), and the pointer array for O(V)O(|V|)—is O(V+E)O(|V| + |E|). The for Dinic's algorithm outlines three key procedures: BFS to construct the level graph, DFS to compute blocking flows by pushing flow along level-respecting paths, and the main loop to repeat phases until saturation. These implement the core logic of building layered networks and finding maximal flows within them without beyond levels. The BFS procedure assigns levels via shortest-path distances in the residual graph:

BFS(s): for each vertex v: l[v] = -1 l[s] = 0 queue Q = empty enqueue s to Q while Q not empty: u = dequeue Q for each adjacent edge to v from u with positive residual capacity: if l[v] == -1: l[v] = l[u] + 1 enqueue v to Q return true if l[t] != -1 else false

BFS(s): for each vertex v: l[v] = -1 l[s] = 0 queue Q = empty enqueue s to Q while Q not empty: u = dequeue Q for each adjacent edge to v from u with positive residual capacity: if l[v] == -1: l[v] = l[u] + 1 enqueue v to Q return true if l[t] != -1 else false

This builds the level graph by exploring only unsaturated edges. The DFS procedure recursively pushes the minimum possible flow along a path from the current vertex, respecting levels and updating pointers:

DFS(u, min_flow, l, ptr): if u == t: return min_flow for i = ptr[u] to end of adj[u]: ptr[u] = i // advance pointer v = target of edge i from u if l[v] == l[u] + 1 and residual capacity (u, v) > 0: pushed = DFS(v, min(min_flow, residual(u, v)), l, ptr) if pushed > 0: augment flow by pushed along the path residual(u, v) -= pushed residual(v, u) += pushed // update reverse return pushed l[u] = -1 // mark as unlevelled for optimization return 0

DFS(u, min_flow, l, ptr): if u == t: return min_flow for i = ptr[u] to end of adj[u]: ptr[u] = i // advance pointer v = target of edge i from u if l[v] == l[u] + 1 and residual capacity (u, v) > 0: pushed = DFS(v, min(min_flow, residual(u, v)), l, ptr) if pushed > 0: augment flow by pushed along the path residual(u, v) -= pushed residual(v, u) += pushed // update reverse return pushed l[u] = -1 // mark as unlevelled for optimization return 0

Multiple calls to DFS from the source compute a blocking flow in the current level graph. The main procedure integrates these to compute the maximum flow:

Dinic(s, t): max_flow = 0 while BFS(s) is true: ptr = [0 for each vertex] // reset pointers while true: pushed = DFS(s, ∞, l, ptr) if pushed == 0: break max_flow += pushed return max_flow

Dinic(s, t): max_flow = 0 while BFS(s) is true: ptr = [0 for each vertex] // reset pointers while true: pushed = DFS(s, ∞, l, ptr) if pushed == 0: break max_flow += pushed return max_flow

This loop repeats level graph construction and blocking flow computation until no path reaches the sink.

Analysis

Time Complexity

Dinic's algorithm has a time complexity of O(V2E)O(V^2 E) for general flow networks, where VV is the number of vertices and EE is the number of edges. This bound arises from the algorithm's phase-based structure, where each phase builds a level graph via (BFS) and computes a blocking flow using (DFS) traversals. The algorithm executes at most V1V-1 phases. In each phase, the shortest path distance from the source to the sink in the residual graph strictly increases by at least 1, and this distance cannot exceed V1V-1. Moreover, each phase saturates the outgoing edges of at least one vertex in the level graph, ensuring progress toward eliminating augmenting paths of the current shortest length. Per phase, the BFS to construct the level graph takes O(V+E)O(V + E) time, as it traverses all vertices and edges in the residual graph. The subsequent blocking flow computation requires O(VE)O(V E) time. Although each individual DFS traversal explores O(E)O(E) edges, the total work across all DFS calls in a phase—accounting for advances along edges, retreats during backtracking, and augmentations—is bounded by O(VE)O(V E), since the level graph is acyclic and each edge is examined at most O(V)O(V) times in aggregate due to the limited depth and pointer optimizations in the DFS implementation. Combining these, the total runtime is O(V(V+E+VE))=O(V2E)O(V \cdot (V + E + V E)) = O(V^2 E). This improves upon the Edmonds-Karp algorithm's O(VE2)O(V E^2) complexity, which relies on O(VE)O(V E) sequential augmentations each taking O(E)O(E) time to find a single path via BFS; Dinic's use of blocking flows enables multiple simultaneous augmentations per phase, drastically reducing the number of iterations needed. In special cases like unit-capacity networks, the algorithm achieves tighter bounds such as O(min(V2/3E,E3/2))O(\min(V^{2/3} E, E^{3/2})) .

Special Cases and Optimizations

In unit-capacity networks, where all edge capacities are one, benefits from a reduced number of phases in level graph construction, leading to a of O(min(V2/3,E1/2)E)O(\min(|V|^{2/3}, |E|^{1/2}) |E|). This improvement arises because the shortest path distances in the residual graph grow more rapidly, bounding the phases by O(min(V2/3,E1/2))O(\min(|V|^{2/3}, |E|^{1/2})), while each blocking flow phase takes O(E)O(|E|) time. For bipartite graphs, Dinic's algorithm applied to unit-capacity networks for maximum matching reduces to the Hopcroft-Karp algorithm, achieving O(V1/2E)O(|V|^{1/2} |E|) time. This equivalence stems from the layered structure aligning with multiple shortest augmenting paths in bipartite matching, where the number of phases is O(V1/2)O(|V|^{1/2}). Further optimizations employ dynamic trees to accelerate blocking flow computation within each phase. By representing the level graph's trees and enabling fast path queries and updates, the time per phase drops to O(ElogV)O(|E| \log |V|), yielding an overall complexity of O(VElogV)O(|V| |E| \log |V|). This enhancement, introduced via the link-cut tree data structure, supports efficient linking and cutting of paths during DFS traversals. Parallel variants of Dinic's algorithm target multi-core architectures by distributing the DFS-based blocking flow searches across threads, improving for dense graphs. These implementations parallelize the traversal of advance vertices while maintaining level graph integrity, achieving speedups on multi-core processors for large networks. In networks with large edge capacities, the worst-case remains O(V2E)O(|V|^2 |E|), as the phase count is bounded by V1|V|-1 independently of capacities. However, practical performance improves due to fewer effective phases, as high-capacity edges allow larger augmentations per blocking flow, reducing iterations in real-world instances.

Example

Network Illustration

To illustrate the setup for applying Dinic's algorithm, consider a simple directed flow network with 5 vertices labeled 1 through 5, where vertex 1 serves as the source ss and vertex 5 as the sink tt. The network consists of directed edges connecting the source to intermediate vertices and ultimately to the sink, each assigned a positive integer capacity representing the maximum flow allowable along that edge. The structure forms multiple paths from ss to tt, including routes through vertices 2 and 3 as intermediaries, and vertex 4 as a convergence point before the sink. The edges and their capacities are as follows:
FromToCapacity
124
133
242
253
343
452
In the initial residual network, the forward residual capacities match the original edge capacities, while backward residual capacities are zero for all edges, as no flow has yet been assigned. This network, as a model for flow problems, has a maximum flow of 5 from source to .

Step-by-Step Execution

To demonstrate the operation of Dinic's algorithm on the example network illustrated earlier, the process begins with an initial zero flow in the residual graph. The algorithm iterates through phases until no path from source node 1 to sink node 5 exists in the residual graph. In the first phase, a breadth-first search (BFS) constructs the level graph by assigning distances from the source as levels: [0, 1, 1, 2, 2] for nodes 1 through 5, respectively. This level graph ensures that all edges point from level ii to level i+1i+1. A blocking flow is then computed within this level graph using depth-first searches to find and augment multiple vertex-disjoint paths from the source to the sink, saturating at least one edge on every possible path in the level graph. This augments flow by 3 units along the path 1-2-5 (the only path in this level graph). The residual graph is updated by reducing forward capacities along the augmented path and increasing reverse capacities accordingly. A second phase follows, as an s-t path still exists in the updated residual graph. BFS recomputes the levels: [0, 1, 1, 2, 3] for nodes 1 through 5. The blocking flow computation again finds augmenting paths in this new level graph, augmenting a total of 2 units along paths such as 1-3-4-5 (e.g., carrying 2 units if explored first, limited by the bottleneck in the residual graph) or 1 unit each along 1-2-4-5 and 1-3-4-5 (depending on the order of DFS traversals), reaching 5 overall. Residual capacities are updated once more. At this point, the residual graph has no remaining s-t path, as confirmed by a final BFS that fails to reach the . The algorithm terminates with a maximum flow of 5.

Applications and Comparisons

Real-World Uses

Dinic's algorithm finds extensive application in bipartite matching problems, where it computes the by modeling the as a . In this setup, a source connects to all vertices in one partite set with unit capacities, edges between the partite sets have infinite capacity, and the other partite set connects to a with unit capacities; the maximum flow value then equals the size of the maximum matching. This approach is particularly efficient for large-scale assignment tasks, such as job scheduling or in computing systems. In transportation and logistics, Dinic's algorithm optimizes the flow of across networks with capacity constraints, such as assigning shipment volumes from warehouses to customers while respecting or limits. For instance, it has been applied to maximize flow in facilities, outperforming simpler max-flow methods by efficiently handling layered network structures to minimize bottlenecks in supply chains. Similarly, it aids in urban optimization by modeling capacities and computing maximum flows to reduce delays. For , Dinic's algorithm supports graph-cut methods by solving the in a graph where pixels represent nodes, and edge weights reflect similarity measures between neighboring pixels. The source and represent foreground and background labels, respectively, allowing the max-flow to partition the effectively. This has been implemented in segmentation pipelines for high-resolution tasks, such as intervertebral disc separation in MRI scans. In , particularly VLSI routing, Dinic's algorithm addresses wire placement under capacity constraints by treating routing channels as flow networks, where nets are flows routed from pins to avoid congestion. It computes maximum routable flows to ensure feasibility in multi-layer layouts, as seen in pin redistribution problems where it efficiently saturates paths in dense graphs. This application enhances overall chip performance by minimizing violations in wire length and timing.

Comparison with Other Algorithms

Dinic's algorithm offers significant improvements over the Edmonds-Karp algorithm, which implements the Ford-Fulkerson method using to find augmenting paths. While Edmonds-Karp has a of O(VE2)O(|V| |E|^2), Dinic's achieves O(V2E)O(|V|^2 |E|) by constructing level graphs and computing blocking flows in each phase, allowing multiple augmenting paths to be found simultaneously rather than one at a time. In practice, this makes Dinic's substantially faster, particularly for graphs with moderate to high edge densities, as blocking flows reduce the number of phases needed. Compared to the preflow-push algorithm developed by Goldberg and Tarjan, Dinic's is generally simpler in structure and easier to implement, relying on explicit level graphs and DFS-based blocking flow searches rather than maintaining preflows and dynamic height labels. The worst-case of preflow-push is O(V3)O(|V|^3), which outperforms Dinic's O(V2E)O(|V|^2 |E|) in dense graphs where E|E| approaches V2|V|^2, but Dinic's holds an advantage in sparser networks due to fewer operations per phase. Preflow-push variants, such as those using highest-label selection, can further enhance practical performance on dense instances, though they increase . The FIFO variant of push-relabel, which processes vertices in first-in-first-out order, improves upon the basic preflow-push for practical but still requires careful management of active vertices and relabeling operations. Dinic's excels in sparse graphs, where its phase-based leverages the lower edge count more effectively, and is often favored in competitive programming settings for its optimal balance of asymptotic speed, practical runtime, and coding simplicity.

References

Add your contribution
Related Hubs
User Avatar
No comments yet.