1use std::collections::VecDeque;
9
10#[derive(Debug, Clone)]
12struct FlowEdge {
13 to: usize,
15 cap: i64,
17 rev: usize,
19}
20
21#[derive(Debug, Clone)]
40pub struct DinicMaxFlow {
41 n: usize,
42 graph: Vec<Vec<FlowEdge>>,
43}
44
45impl DinicMaxFlow {
46 pub fn new(n: usize) -> Self {
48 Self {
49 n,
50 graph: vec![vec![]; n],
51 }
52 }
53
54 pub fn add_edge(&mut self, u: usize, v: usize, cap: i64) {
57 let rev_u = self.graph[v].len();
58 let rev_v = self.graph[u].len();
59 self.graph[u].push(FlowEdge {
60 to: v,
61 cap,
62 rev: rev_u,
63 });
64 self.graph[v].push(FlowEdge {
65 to: u,
66 cap: 0,
67 rev: rev_v,
68 });
69 }
70
71 pub fn max_flow(&mut self, source: usize, sink: usize) -> i64 {
74 if source >= self.n || sink >= self.n {
75 return 0;
76 }
77 let mut total = 0i64;
78 while let Some(level) = self.bfs(source, sink) {
79 let mut iter: Vec<usize> = vec![0; self.n];
80 loop {
81 let f = self.dfs(source, sink, i64::MAX, &level, &mut iter);
82 if f == 0 {
83 break;
84 }
85 total += f;
86 }
87 }
88 total
89 }
90
91 fn bfs(&self, source: usize, sink: usize) -> Option<Vec<i64>> {
93 let mut level = vec![-1i64; self.n];
94 level[source] = 0;
95 let mut queue = VecDeque::new();
96 queue.push_back(source);
97 while let Some(v) = queue.pop_front() {
98 for e in &self.graph[v] {
99 if e.cap > 0 && level[e.to] < 0 {
100 level[e.to] = level[v] + 1;
101 queue.push_back(e.to);
102 }
103 }
104 }
105 if level[sink] < 0 {
106 None
107 } else {
108 Some(level)
109 }
110 }
111
112 fn dfs(
114 &mut self,
115 v: usize,
116 sink: usize,
117 pushed: i64,
118 level: &[i64],
119 iter: &mut Vec<usize>,
120 ) -> i64 {
121 if v == sink {
122 return pushed;
123 }
124 while iter[v] < self.graph[v].len() {
125 let i = iter[v];
126 let (to, cap, rev) = {
127 let e = &self.graph[v][i];
128 (e.to, e.cap, e.rev)
129 };
130 if cap > 0 && level[v] < level[to] {
131 let d = self.dfs(to, sink, pushed.min(cap), level, iter);
132 if d > 0 {
133 self.graph[v][i].cap -= d;
134 self.graph[to][rev].cap += d;
135 return d;
136 }
137 }
138 iter[v] += 1;
139 }
140 0
141 }
142
143 pub fn edges(&self) -> Vec<(usize, usize, i64, i64)> {
146 let mut result = Vec::new();
147 for u in 0..self.n {
148 for e in &self.graph[u] {
149 let original_cap = e.cap + self.graph[e.to][e.rev].cap;
156 if original_cap > 0 {
157 let flow = original_cap - e.cap;
158 result.push((u, e.to, original_cap, flow));
159 }
160 }
161 }
162 result
163 }
164}
165
166#[derive(Debug, Clone)]
188pub struct PushRelabelMaxFlow {
189 n: usize,
190 graph: Vec<Vec<FlowEdge>>,
191}
192
193impl PushRelabelMaxFlow {
194 pub fn new(n: usize) -> Self {
196 Self {
197 n,
198 graph: vec![vec![]; n],
199 }
200 }
201
202 pub fn add_edge(&mut self, u: usize, v: usize, cap: i64) {
204 let rev_u = self.graph[v].len();
205 let rev_v = self.graph[u].len();
206 self.graph[u].push(FlowEdge {
207 to: v,
208 cap,
209 rev: rev_u,
210 });
211 self.graph[v].push(FlowEdge {
212 to: u,
213 cap: 0,
214 rev: rev_v,
215 });
216 }
217
218 pub fn max_flow(&mut self, source: usize, sink: usize) -> i64 {
220 if source >= self.n || sink >= self.n || source == sink {
221 return 0;
222 }
223 let n = self.n;
224 let mut height = vec![0i64; n];
225 let mut excess = vec![0i64; n];
226 let mut current = vec![0usize; n];
227
228 height[source] = n as i64;
230 for i in 0..self.graph[source].len() {
231 let (to, cap, rev) = {
232 let e = &self.graph[source][i];
233 (e.to, e.cap, e.rev)
234 };
235 if cap > 0 {
236 excess[to] += cap;
237 excess[source] -= cap;
238 self.graph[source][i].cap = 0;
239 self.graph[to][rev].cap += cap;
240 }
241 }
242
243 let mut buckets: Vec<VecDeque<usize>> = vec![VecDeque::new(); 2 * n + 1];
246 let mut in_queue = vec![false; n];
247 for v in 0..n {
248 if v != source && v != sink && excess[v] > 0 {
249 let h = height[v] as usize;
250 buckets[h].push_back(v);
251 in_queue[v] = true;
252 }
253 }
254
255 let mut highest = n - 1;
256
257 loop {
258 while highest > 0 && buckets[highest].is_empty() {
260 if highest == 0 {
261 break;
262 }
263 highest -= 1;
264 }
265 if buckets[highest].is_empty() {
266 break;
267 }
268 let v = match buckets[highest].front().copied() {
269 Some(x) => x,
270 None => break,
271 };
272
273 while excess[v] > 0 {
275 if current[v] == self.graph[v].len() {
276 let min_h = self.graph[v]
278 .iter()
279 .filter(|e| e.cap > 0)
280 .map(|e| height[e.to])
281 .min()
282 .unwrap_or(2 * n as i64);
283 height[v] = min_h + 1;
284 current[v] = 0;
285 let old_h = highest;
287 let _ = buckets[old_h].pop_front();
288 in_queue[v] = false;
289 let new_h = height[v] as usize;
290 if new_h < 2 * n {
291 buckets[new_h].push_front(v);
292 in_queue[v] = true;
293 if new_h > highest {
294 highest = new_h;
295 }
296 }
297 break;
298 }
299 let i = current[v];
300 let (to, cap, rev) = {
301 let e = &self.graph[v][i];
302 (e.to, e.cap, e.rev)
303 };
304 if cap > 0 && height[v] == height[to] + 1 {
305 let pushed = excess[v].min(cap);
306 excess[v] -= pushed;
307 excess[to] += pushed;
308 self.graph[v][i].cap -= pushed;
309 self.graph[to][rev].cap += pushed;
310
311 if to != source && to != sink && !in_queue[to] && excess[to] > 0 {
312 let h = height[to] as usize;
313 if h < 2 * n {
314 buckets[h].push_back(to);
315 in_queue[to] = true;
316 if h > highest {
317 highest = h;
318 }
319 }
320 }
321 } else {
322 current[v] += 1;
323 }
324 }
325
326 if excess[v] == 0 {
328 if let Some(&front) = buckets[highest].front() {
329 if front == v {
330 buckets[highest].pop_front();
331 in_queue[v] = false;
332 }
333 }
334 }
335 }
336
337 excess[sink].max(0)
338 }
339}
340
341#[derive(Debug, Clone)]
363pub struct EdmondsKarp {
364 n: usize,
365 graph: Vec<Vec<FlowEdge>>,
366}
367
368impl EdmondsKarp {
369 pub fn new(n: usize) -> Self {
371 Self {
372 n,
373 graph: vec![vec![]; n],
374 }
375 }
376
377 pub fn add_edge(&mut self, u: usize, v: usize, cap: i64) {
379 let rev_u = self.graph[v].len();
380 let rev_v = self.graph[u].len();
381 self.graph[u].push(FlowEdge {
382 to: v,
383 cap,
384 rev: rev_u,
385 });
386 self.graph[v].push(FlowEdge {
387 to: u,
388 cap: 0,
389 rev: rev_v,
390 });
391 }
392
393 pub fn max_flow(&mut self, source: usize, sink: usize) -> i64 {
395 if source >= self.n || sink >= self.n {
396 return 0;
397 }
398 let mut total = 0i64;
399 loop {
400 let mut parent: Vec<Option<(usize, usize)>> = vec![None; self.n];
402 parent[source] = Some((source, 0));
403 let mut queue = VecDeque::new();
404 queue.push_back(source);
405 'bfs: while let Some(v) = queue.pop_front() {
406 for (i, e) in self.graph[v].iter().enumerate() {
407 if e.cap > 0 && parent[e.to].is_none() {
408 parent[e.to] = Some((v, i));
409 if e.to == sink {
410 break 'bfs;
411 }
412 queue.push_back(e.to);
413 }
414 }
415 }
416 if parent[sink].is_none() {
417 break;
418 }
419 let mut bottleneck = i64::MAX;
421 let mut node = sink;
422 while node != source {
423 let (prev, ei) = match parent[node] {
424 Some(p) => p,
425 None => break,
426 };
427 bottleneck = bottleneck.min(self.graph[prev][ei].cap);
428 node = prev;
429 }
430 let mut node = sink;
432 while node != source {
433 let (prev, ei) = match parent[node] {
434 Some(p) => p,
435 None => break,
436 };
437 let rev = self.graph[prev][ei].rev;
438 self.graph[prev][ei].cap -= bottleneck;
439 self.graph[node][rev].cap += bottleneck;
440 node = prev;
441 }
442 total += bottleneck;
443 }
444 total
445 }
446}
447
448#[cfg(test)]
449mod tests {
450 use super::*;
451
452 fn simple_graph() -> (usize, Vec<(usize, usize, i64)>) {
453 (
455 4,
456 vec![(0, 1, 10), (0, 2, 10), (1, 3, 10), (2, 3, 10), (1, 2, 1)],
457 )
458 }
459
460 #[test]
461 fn test_dinic_simple() {
462 let (n, edges) = simple_graph();
463 let mut d = DinicMaxFlow::new(n);
464 for (u, v, c) in &edges {
465 d.add_edge(*u, *v, *c);
466 }
467 assert_eq!(d.max_flow(0, 3), 20);
468 }
469
470 #[test]
471 fn test_push_relabel_simple() {
472 let (n, edges) = simple_graph();
473 let mut pr = PushRelabelMaxFlow::new(n);
474 for (u, v, c) in &edges {
475 pr.add_edge(*u, *v, *c);
476 }
477 assert_eq!(pr.max_flow(0, 3), 20);
478 }
479
480 #[test]
481 fn test_edmonds_karp_simple() {
482 let (n, edges) = simple_graph();
483 let mut ek = EdmondsKarp::new(n);
484 for (u, v, c) in &edges {
485 ek.add_edge(*u, *v, *c);
486 }
487 assert_eq!(ek.max_flow(0, 3), 20);
488 }
489
490 #[test]
491 fn test_dinic_no_path() {
492 let mut d = DinicMaxFlow::new(3);
493 d.add_edge(0, 1, 5);
494 assert_eq!(d.max_flow(0, 2), 0);
496 }
497
498 #[test]
499 fn test_edmonds_karp_bottleneck() {
500 let mut ek = EdmondsKarp::new(3);
501 ek.add_edge(0, 1, 100);
502 ek.add_edge(1, 2, 1);
503 assert_eq!(ek.max_flow(0, 2), 1);
504 }
505
506 #[test]
507 fn test_dinic_cycle() {
508 let mut d = DinicMaxFlow::new(4);
510 d.add_edge(0, 1, 5);
511 d.add_edge(1, 2, 3);
512 d.add_edge(2, 1, 2);
513 d.add_edge(1, 3, 4);
514 d.add_edge(2, 3, 3);
515 assert_eq!(d.max_flow(0, 3), 5);
517 }
518
519 #[test]
520 fn test_push_relabel_larger() {
521 let mut pr = PushRelabelMaxFlow::new(6);
523 pr.add_edge(0, 1, 16);
524 pr.add_edge(0, 2, 13);
525 pr.add_edge(1, 2, 10);
526 pr.add_edge(1, 3, 12);
527 pr.add_edge(2, 1, 4);
528 pr.add_edge(2, 4, 14);
529 pr.add_edge(3, 2, 9);
530 pr.add_edge(3, 5, 20);
531 pr.add_edge(4, 3, 7);
532 pr.add_edge(4, 5, 4);
533 assert_eq!(pr.max_flow(0, 5), 23);
534 }
535
536 #[test]
537 fn test_dinic_clrs_example() {
538 let mut d = DinicMaxFlow::new(6);
539 d.add_edge(0, 1, 16);
540 d.add_edge(0, 2, 13);
541 d.add_edge(1, 2, 10);
542 d.add_edge(1, 3, 12);
543 d.add_edge(2, 1, 4);
544 d.add_edge(2, 4, 14);
545 d.add_edge(3, 2, 9);
546 d.add_edge(3, 5, 20);
547 d.add_edge(4, 3, 7);
548 d.add_edge(4, 5, 4);
549 assert_eq!(d.max_flow(0, 5), 23);
550 }
551
552 #[test]
553 fn test_zero_capacity() {
554 let mut d = DinicMaxFlow::new(2);
555 d.add_edge(0, 1, 0);
556 assert_eq!(d.max_flow(0, 1), 0);
557 }
558
559 #[test]
560 fn test_single_edge() {
561 let mut d = DinicMaxFlow::new(2);
562 d.add_edge(0, 1, 42);
563 assert_eq!(d.max_flow(0, 1), 42);
564 }
565
566 #[test]
567 fn test_all_three_agree() {
568 let edges = vec![
570 (0usize, 1usize, 7i64),
571 (0, 2, 4),
572 (1, 3, 3),
573 (1, 4, 5),
574 (2, 4, 4),
575 (3, 5, 5),
576 (4, 5, 6),
577 ];
578 let n = 6;
579 let mut d = DinicMaxFlow::new(n);
580 let mut pr = PushRelabelMaxFlow::new(n);
581 let mut ek = EdmondsKarp::new(n);
582 for &(u, v, c) in &edges {
583 d.add_edge(u, v, c);
584 pr.add_edge(u, v, c);
585 ek.add_edge(u, v, c);
586 }
587 let fd = d.max_flow(0, 5);
588 let fpr = pr.max_flow(0, 5);
589 let fek = ek.max_flow(0, 5);
590 assert_eq!(fd, fpr, "Dinic vs PushRelabel mismatch");
591 assert_eq!(fd, fek, "Dinic vs EdmondsKarp mismatch");
592 }
593}