1818
1919
2020class Dinic :
21- def __init__ (self , n : int ):
21+ """
22+ Implements Dinic's Algorithm for finding the Maximum Flow in a flow network.
23+ """
24+
25+ def __init__ (self , n : int ) -> None :
2226 """
2327 Initialize the Dinic algorithm with n nodes.
24- Nodes are 0-indexed.
28+
29+ Args:
30+ n: Total number of nodes in the network. Nodes are 0-indexed.
2531 """
2632 self .n = n
27- self .graph = [[] for _ in range (n )]
28- self .level = []
33+ self .graph : list [ list [ list [ int ]]] = [[] for _ in range (n )]
34+ self .level : list [ int ] = []
2935
3036 def add_edge (self , u : int , v : int , capacity : int ) -> None :
3137 """
32- Adds a directed edge with a capacity.
33- Note: Stores indices to handle the residual edges efficiently.
38+ Adds a directed edge with a specified capacity to the graph.
39+
40+ Note: This stores indices to handle residual edges efficiently.
41+
42+ Args:
43+ u: Source node index.
44+ v: Destination node index.
45+ capacity: Capacity of the edge.
3446 """
3547 # Forward edge: [v, capacity, index_of_reverse_edge]
3648 self .graph [u ].append ([v , capacity , len (self .graph [v ])])
@@ -41,11 +53,19 @@ def bfs(self, source: int, sink: int) -> bool:
4153 """
4254 Builds the Level Graph (L_G) using BFS.
4355 Corresponds to the INITIALIZE step in the Even-Itai refinement.
44- Returns True if the sink is reachable, False otherwise.
56+
57+ Args:
58+ source: The source node index.
59+ sink: The sink (target) node index.
60+
61+ Returns:
62+ True if the sink is reachable from the source in the residual graph,
63+ False otherwise.
4564 """
4665 self .level = [- 1 ] * self .n
4766 self .level [source ] = 0
48- # using list as queue to avoid importing collections.deque
67+ # Using list as queue to avoid importing collections.deque
68+ # to adhere to "no external imports" policy.
4969 queue = [source ]
5070
5171 while queue :
@@ -57,19 +77,20 @@ def bfs(self, source: int, sink: int) -> bool:
5777
5878 return self .level [sink ] >= 0
5979
60- def dfs (self , u : int , sink : int , flow : int , ptr : list ) -> int :
80+ def dfs (self , u : int , sink : int , flow : int , ptr : list [ int ] ) -> int :
6181 """
62- Finds a blocking flow in the Level Graph.
82+ Finds a blocking flow in the Level Graph using DFS .
6383 Combines the ADVANCE and RETREAT steps.
6484
6585 Args:
6686 u: Current node.
6787 sink: Target node.
68- flow: Current flow bottleneck.
69- ptr: Current arc pointers (to implement 'Remove saturated edges').
88+ flow: Current flow bottleneck along the path.
89+ ptr: List of current arc pointers for each node (to implement
90+ 'Remove saturated edges' optimization).
7091
7192 Returns:
72- The amount of flow pushed.
93+ The amount of flow successfully pushed from u to sink .
7394 """
7495 if u == sink or flow == 0 :
7596 return flow
@@ -98,19 +119,31 @@ def max_flow(self, source: int, sink: int) -> int:
98119 """
99120 Computes the maximum flow from source to sink.
100121
101- >>> dinic = Dinic(6)
102- >>> dinic.add_edge(0, 1, 16)
103- >>> dinic.add_edge(0, 2, 13)
104- >>> dinic.add_edge(1, 2, 10)
105- >>> dinic.add_edge(1, 3, 12)
106- >>> dinic.add_edge(2, 1, 4)
107- >>> dinic.add_edge(2, 4, 14)
108- >>> dinic.add_edge(3, 2, 9)
109- >>> dinic.add_edge(3, 5, 20)
110- >>> dinic.add_edge(4, 3, 7)
111- >>> dinic.add_edge(4, 5, 4)
112- >>> dinic.max_flow(0, 5)
113- 23
122+ Time Complexity:
123+ - O(V^2 * E) for general networks.
124+ - O(E * sqrt(V)) for unit networks (e.g., Bipartite Matching).
125+
126+ Args:
127+ source: The source node index.
128+ sink: The sink (target) node index.
129+
130+ Returns:
131+ The maximum flow value.
132+
133+ Examples:
134+ >>> dinic = Dinic(6)
135+ >>> dinic.add_edge(0, 1, 16)
136+ >>> dinic.add_edge(0, 2, 13)
137+ >>> dinic.add_edge(1, 2, 10)
138+ >>> dinic.add_edge(1, 3, 12)
139+ >>> dinic.add_edge(2, 1, 4)
140+ >>> dinic.add_edge(2, 4, 14)
141+ >>> dinic.add_edge(3, 2, 9)
142+ >>> dinic.add_edge(3, 5, 20)
143+ >>> dinic.add_edge(4, 3, 7)
144+ >>> dinic.add_edge(4, 5, 4)
145+ >>> dinic.max_flow(0, 5)
146+ 23
114147 """
115148 max_f = 0
116149 # While we can build a Level Graph (source can reach sink)
@@ -146,4 +179,4 @@ def max_flow(self, source: int, sink: int) -> int:
146179 for u , v , c in edges :
147180 dn .add_edge (u , v , c )
148181
149- print (f"Maximum Flow: { dn .max_flow (0 , 5 )} " )
182+ print (f"Maximum Flow: { dn .max_flow (0 , 5 )} " )
0 commit comments