algorithms_edu/algo/graph/network_flow/
dinic.rs1use super::{Edge, MaxFlowSolver, NetworkFlowAdjacencyList};
13use std::{cell::RefCell, collections::VecDeque, rc::Rc};
14pub struct DinicSolver<'a> {
15 g: &'a mut NetworkFlowAdjacencyList,
16 n: usize,
17 levels: Vec<isize>,
18}
19
20const INF: i32 = i32::MAX / 2;
21
22impl<'a> DinicSolver<'a> {
23 fn init(g: &'a mut NetworkFlowAdjacencyList) -> Self {
24 let n = g.node_count();
25 Self {
26 g,
27 n,
28 levels: vec![0; n],
29 }
30 }
31 fn solve(&mut self) -> i32 {
32 let mut max_flow = 0;
33
34 while self.bfs() {
35 let mut next = vec![0usize; self.n];
38 let mut f = -1;
40 while f != 0 {
41 f = self.dfs(self.g.source, &mut next, INF);
42 max_flow += f;
43 }
44 }
45 max_flow
46 }
47
48 fn bfs(&mut self) -> bool {
54 self.levels = vec![-1; self.n];
55 self.levels[self.g.source] = 0;
56 let mut q = VecDeque::with_capacity(self.n);
57 q.push_back(self.g.source);
58 while let Some(node) = q.pop_front() {
59 for edge in &self.g[node] {
60 let edge = edge.borrow();
61 let rcap = edge.reamaining_capacity();
62 if rcap > 0 && self.levels[edge.to] == -1 {
63 self.levels[edge.to] = self.levels[node] + 1;
64 q.push_back(edge.to)
65 }
66 }
67 }
68 self.levels[self.g.sink] != -1
69 }
70
71 fn dfs(&mut self, at: usize, next: &mut [usize], flow: i32) -> i32 {
72 if at == self.g.sink {
73 return flow;
74 }
75 let num_edges = self.g[at].len();
76 while next[at] < num_edges {
77 let edge = unsafe { &*(&self.g[at][next[at]] as *const Rc<RefCell<Edge>>) };
78 let mut _edge = edge.borrow_mut();
79 let rcap = _edge.reamaining_capacity();
80 if rcap > 0 && self.levels[_edge.to] == self.levels[at] + 1 {
81 let bottleneck = self.dfs(_edge.to, next, std::cmp::min(flow, rcap));
82 if bottleneck > 0 {
83 _edge.augment(bottleneck);
84 return bottleneck;
85 }
86 }
87 next[at] += 1;
88 }
89
90 0
91 }
92}
93
94impl<'a> MaxFlowSolver for DinicSolver<'a> {
95 fn max_flow(graph: &mut NetworkFlowAdjacencyList) -> i32 {
96 let mut s = DinicSolver::init(graph);
97 s.solve()
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 fn test_max_flow(n: usize, edges: &[(usize, usize, i32)], expected_max_flow: i32) {
106 let mut graph = NetworkFlowAdjacencyList::from_edges(n, edges);
107 let max_flow = DinicSolver::max_flow(&mut graph);
108 assert_eq!(max_flow, expected_max_flow);
109 }
110
111 #[test]
112 fn test_small_graph() {
113 test_max_flow(
114 6,
115 &[
116 (5, 0, 10),
118 (5, 1, 10),
119 (2, 4, 10),
121 (3, 4, 10),
122 (0, 1, 2),
124 (0, 2, 4),
125 (0, 3, 8),
126 (1, 3, 9),
127 (3, 2, 6),
128 ],
129 19,
130 );
131 }
132
133 #[test]
134 fn test_disconnected() {
135 test_max_flow(4, &[(3, 0, 9), (1, 2, 9)], 0);
136 }
137
138 #[test]
139 fn test_medium_graph() {
140 test_max_flow(
141 12,
142 &[
143 (11, 0, 5),
145 (11, 1, 20),
146 (11, 2, 10),
147 (7, 10, 7),
149 (8, 10, 15),
150 (9, 10, 60),
151 (0, 1, 3),
153 (0, 5, 4),
154 (1, 4, 14),
155 (1, 5, 14),
156 (2, 1, 5),
157 (2, 3, 4),
158 (3, 4, 3),
159 (3, 9, 11),
160 (4, 6, 4),
161 (4, 8, 22),
162 (5, 6, 8),
163 (5, 7, 3),
164 (6, 7, 12),
165 (7, 8, 9),
166 (8, 9, 11),
167 ],
168 29,
169 );
170 }
171}