contest_algorithms/graph/
flow.rs1use super::{AdjListIterator, Graph};
3
4pub struct FlowGraph {
6 pub graph: Graph,
8 pub cap: Vec<i64>,
10 pub cost: Vec<i64>,
12}
13
14impl FlowGraph {
15 const INF: i64 = 0x3f3f_3f3f_3f3f_3f3f;
17
18 pub fn new(vmax: usize, emax_hint: usize) -> Self {
20 Self {
21 graph: Graph::new(vmax, 2 * emax_hint),
22 cap: Vec::with_capacity(2 * emax_hint),
23 cost: Vec::with_capacity(2 * emax_hint),
24 }
25 }
26
27 pub fn add_edge(&mut self, u: usize, v: usize, cap: i64, rcap: i64, cost: i64) {
30 self.cap.push(cap);
31 self.cap.push(rcap);
32 self.cost.push(cost);
33 self.cost.push(-cost);
34 self.graph.add_undirected_edge(u, v);
35 }
36
37 pub fn dinic(&self, s: usize, t: usize) -> (i64, Vec<i64>) {
46 let mut flow = vec![0; self.graph.num_e()];
47 let mut max_flow = 0;
48 loop {
49 let dist = self.dinic_search(s, &flow);
50 if dist[t] == Self::INF {
51 break;
52 }
53 let mut adj_iters = (0..self.graph.num_v())
55 .map(|u| self.graph.adj_list(u).peekable())
56 .collect::<Vec<_>>();
57 max_flow += self.dinic_augment(s, t, Self::INF, &dist, &mut adj_iters, &mut flow);
58 }
59 (max_flow, flow)
60 }
61
62 fn dinic_search(&self, s: usize, flow: &[i64]) -> Vec<i64> {
64 let mut dist = vec![Self::INF; self.graph.num_v()];
65 let mut q = ::std::collections::VecDeque::new();
66 dist[s] = 0;
67 q.push_back(s);
68 while let Some(u) = q.pop_front() {
69 for (e, v) in self.graph.adj_list(u) {
70 if dist[v] == Self::INF && flow[e] < self.cap[e] {
71 dist[v] = dist[u] + 1;
72 q.push_back(v);
73 }
74 }
75 }
76 dist
77 }
78
79 fn dinic_augment(
81 &self,
82 u: usize,
83 t: usize,
84 f: i64,
85 dist: &[i64],
86 adj: &mut [::std::iter::Peekable<AdjListIterator>],
87 flow: &mut [i64],
88 ) -> i64 {
89 if u == t {
90 return f;
91 }
92 let mut df = 0;
93
94 while let Some(&(e, v)) = adj[u].peek() {
95 let rem_cap = (self.cap[e] - flow[e]).min(f - df);
96 if rem_cap > 0 && dist[v] == dist[u] + 1 {
97 let cf = self.dinic_augment(v, t, rem_cap, dist, adj, flow);
98 flow[e] += cf;
99 flow[e ^ 1] -= cf;
100 df += cf;
101 if df == f {
102 break;
103 }
104 }
105 adj[u].next();
107 }
108 df
109 }
110
111 pub fn min_cut(&self, dist: &[i64]) -> Vec<usize> {
113 (0..self.graph.num_e())
114 .filter(|&e| {
115 let u = self.graph.endp[e ^ 1];
116 let v = self.graph.endp[e];
117 dist[u] < Self::INF && dist[v] == Self::INF
118 })
119 .collect()
120 }
121
122 pub fn mcf(&self, s: usize, t: usize) -> (i64, i64, Vec<i64>) {
129 let mut pot = vec![0; self.graph.num_v()];
130
131 for _ in 1..self.graph.num_v() {
133 for e in 0..self.graph.num_e() {
134 if self.cap[e] > 0 {
135 let u = self.graph.endp[e ^ 1];
136 let v = self.graph.endp[e];
137 pot[v] = pot[v].min(pot[u] + self.cost[e]);
138 }
139 }
140 }
141
142 let mut flow = vec![0; self.graph.num_e()];
143 let (mut min_cost, mut max_flow) = (0, 0);
144 loop {
145 let par = self.mcf_search(s, &flow, &mut pot);
146 if par[t] == None {
147 break;
148 }
149 let (dc, df) = self.mcf_augment(t, &par, &mut flow);
150 min_cost += dc;
151 max_flow += df;
152 }
153 (min_cost, max_flow, flow)
154 }
155
156 fn mcf_search(&self, s: usize, flow: &[i64], pot: &mut [i64]) -> Vec<Option<usize>> {
159 let mut vis = vec![false; self.graph.num_v()];
160 let mut dist = vec![Self::INF; self.graph.num_v()];
161 let mut par = vec![None; self.graph.num_v()];
162
163 dist[s] = 0;
164 while let Some(u) = (0..self.graph.num_v())
165 .filter(|&u| !vis[u] && dist[u] < Self::INF)
166 .min_by_key(|&u| dist[u] - pot[u])
167 {
168 vis[u] = true;
169 pot[u] = dist[u];
170 for (e, v) in self.graph.adj_list(u) {
171 if dist[v] > dist[u] + self.cost[e] && flow[e] < self.cap[e] {
172 dist[v] = dist[u] + self.cost[e];
173 par[v] = Some(e);
174 }
175 }
176 }
177 par
178 }
179
180 fn mcf_augment(&self, t: usize, par: &[Option<usize>], flow: &mut [i64]) -> (i64, i64) {
182 let (mut dc, mut df) = (0, Self::INF);
183 let mut u = t;
184 while let Some(e) = par[u] {
185 df = df.min(self.cap[e] - flow[e]);
186 u = self.graph.endp[e ^ 1];
187 }
188 u = t;
189 while let Some(e) = par[u] {
190 flow[e] += df;
191 flow[e ^ 1] -= df;
192 dc += df * self.cost[e];
193 u = self.graph.endp[e ^ 1];
194 }
195 (dc, df)
196 }
197}
198
199#[cfg(test)]
200mod test {
201 use super::*;
202
203 #[test]
204 fn test_basic_flow() {
205 let mut graph = FlowGraph::new(3, 2);
206 graph.add_edge(0, 1, 4, 0, 0);
207 graph.add_edge(1, 2, 3, 0, 0);
208
209 let flow = graph.dinic(0, 2).0;
210 assert_eq!(flow, 3);
211 }
212
213 #[test]
214 fn test_min_cost_flow() {
215 let mut graph = FlowGraph::new(4, 4);
216 graph.add_edge(0, 1, 10, 0, -10);
217 graph.add_edge(1, 2, 7, 0, 8);
218 graph.add_edge(2, 3, 7, 0, 8);
219 graph.add_edge(1, 3, 7, 0, 10);
220
221 let (cost, flow, _) = graph.mcf(0, 3);
222 assert_eq!(cost, 18);
223 assert_eq!(flow, 10);
224 }
225
226 #[test]
227 fn test_max_matching() {
228 let mut graph = FlowGraph::new(14, 4);
229
230 let source = 0;
231 let sink = 13;
232
233 let left_start = 1;
235 let right_start = 7;
237
238 for lhs_vertex in left_start..left_start + 6 {
240 graph.add_edge(source, lhs_vertex, 1, 0, 0);
241 }
242
243 for rhs_vertex in right_start..right_start + 6 {
244 graph.add_edge(rhs_vertex, sink, 1, 0, 0);
245 }
246
247 graph.add_edge(left_start + 0, right_start + 1, 1, 0, 0);
248 graph.add_edge(left_start + 0, right_start + 2, 1, 0, 0);
249 graph.add_edge(left_start + 2, right_start + 0, 1, 0, 0);
250 graph.add_edge(left_start + 2, right_start + 3, 1, 0, 0);
251 graph.add_edge(left_start + 3, right_start + 2, 1, 0, 0);
252 graph.add_edge(left_start + 4, right_start + 2, 1, 0, 0);
253 graph.add_edge(left_start + 4, right_start + 3, 1, 0, 0);
254 graph.add_edge(left_start + 5, right_start + 5, 1, 0, 0);
255
256 let (flow_amt, flow) = graph.dinic(source, sink);
257 assert_eq!(flow_amt, 5);
258
259 let left_right_edges = flow
261 .into_iter()
262 .enumerate()
263 .filter(|&(_e, f)| f > 0)
264 .map(|(e, _f)| (graph.graph.endp[e ^ 1], graph.graph.endp[e]))
266 .filter(|&(u, v)| u != source && v != sink)
268 .collect::<Vec<_>>();
269
270 assert_eq!(
271 left_right_edges,
272 vec![(1, 8), (3, 7), (4, 9), (5, 10), (6, 12)]
273 );
274 }
275}