cp_library_rs/graph/
ford_fulkerson.rs1use num_traits::PrimInt;
4use rustc_hash::FxHashMap;
5
6#[derive(Debug, Clone)]
7pub struct Edge<T> {
8 rev: usize,
10 from: usize,
11 to: usize,
12 cap: T,
13 original_cap: T,
14}
15
16impl<T: Clone> Edge<T> {
17 pub fn new(rev: usize, from: usize, to: usize, cap: T) -> Self {
18 Self {
19 rev,
20 from,
21 to,
22 cap: cap.clone(),
23 original_cap: cap,
24 }
25 }
26}
27
28type Graph<T> = Vec<Vec<Edge<T>>>;
29
30#[derive(Debug)]
32pub struct FordFulkerson<T> {
33 N: usize,
34 pub G: Graph<T>,
36 edge_id: FxHashMap<(usize, usize), usize>,
38}
39
40impl<T: PrimInt> FordFulkerson<T> {
41 pub fn new(n: usize) -> Self {
42 Self {
43 N: n,
44 G: vec![vec![]; n],
45 edge_id: FxHashMap::default(),
46 }
47 }
48
49 pub fn add_edge(&mut self, from: usize, to: usize, cap: T) {
51 let rev = self.G[to].len();
52 self.G[from].push(Edge::new(rev, from, to, cap));
53 let rrev = self.G[from].len() - 1;
55 self.G[to].push(Edge::new(rrev, to, from, T::zero()));
56 self.edge_id.insert((from, to), rrev);
58 }
59
60 fn dfs(u: usize, t: usize, f: T, G: &mut Graph<T>, visit: &mut [bool]) -> T {
62 if u == t {
63 return f;
64 }
65 visit[u] = true;
66 for i in 0..G[u].len() {
67 let v = G[u][i].to;
68 let cap = G[u][i].cap;
69 if visit[v] || cap <= T::zero() {
70 continue;
71 }
72 let d = Self::dfs(v, t, f.min(cap), G, visit);
73 if d > T::zero() {
74 G[u][i].cap = cap - d;
76 let r = G[u][i].rev;
78 G[v][r].cap = G[v][r].cap + d;
79
80 return d;
81 }
82 }
83 T::zero()
84 }
85
86 pub fn max_flow(&mut self, s: usize, t: usize) -> T {
88 let mut flow = T::zero();
89 let mut visit = vec![false; self.N];
90 loop {
91 visit.fill(false);
92 let f = Self::dfs(s, t, T::max_value(), &mut self.G, &mut visit);
94 if f.is_zero() {
95 break;
96 }
97 flow = flow + f;
98 }
99 flow
100 }
101
102 pub fn get_flow(&self, u: usize, v: usize) -> T {
104 let i = self.edge_id[&(u, v)];
105 let cap = self.G[u][i].cap;
106 let original = self.G[u][i].original_cap;
107 original - cap
108 }
109}