Skip to content

Commit c6a6d2c

Browse files
Merge branch 'feature/segtree' into feature/lazysegtree
2 parents 14ed754 + 2e3b0be commit c6a6d2c

File tree

3 files changed

+389
-0
lines changed

3 files changed

+389
-0
lines changed

examples/practice2_d_maxflow.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use ac_library_rs::MfGraph;
2+
use std::io::Read;
3+
4+
#[allow(clippy::many_single_char_names)]
5+
#[allow(clippy::needless_range_loop)]
6+
fn main() {
7+
const N: usize = 128;
8+
9+
let mut buf = String::new();
10+
std::io::stdin().read_to_string(&mut buf).unwrap();
11+
let mut input = buf.split_whitespace();
12+
13+
let n: usize = input.next().unwrap().parse().unwrap();
14+
let m: usize = input.next().unwrap().parse().unwrap();
15+
let mut s = vec![vec![false; N]; N];
16+
for i in 1..=n {
17+
for (j, c) in (1..=m).zip(input.next().unwrap().chars()) {
18+
s[i][j] = c == '.';
19+
}
20+
}
21+
22+
let dy = [1, 0, -1, 0];
23+
let dx = [0, 1, 0, -1];
24+
let c = "v>^<".chars().collect::<Vec<_>>();
25+
let mut graph = MfGraph::<i32>::new(128 * 128);
26+
27+
for i in 1..=n {
28+
for j in 1..=m {
29+
if (i + j) % 2 == 0 {
30+
graph.add_edge(0, i * N + j, 1);
31+
for (dy, dx) in dy.iter().zip(dx.iter()) {
32+
let k = (i as i32 + dy) as usize;
33+
let l = (j as i32 + dx) as usize;
34+
if s[i][j] && s[k][l] {
35+
graph.add_edge(i * N + j, k * N + l, 1);
36+
}
37+
}
38+
} else {
39+
graph.add_edge(i * N + j, 1, 1);
40+
}
41+
}
42+
}
43+
println!("{}", graph.flow(0, 1));
44+
let mut res: Vec<Vec<_>> = (1..=n)
45+
.map(|i| (1..=m).map(|j| if s[i][j] { '.' } else { '#' }).collect())
46+
.collect();
47+
for e in graph.edges() {
48+
let i = e.from / N;
49+
let j = e.from % N;
50+
let k = e.to / N;
51+
let l = e.to % N;
52+
if e.flow == 1 {
53+
for h in 0..4 {
54+
if i as i32 + dy[h] == k as i32 && j as i32 + dx[h] == l as i32 {
55+
res[i - 1][j - 1] = c[h];
56+
res[k - 1][l - 1] = c[h ^ 2];
57+
}
58+
}
59+
}
60+
}
61+
for s in res {
62+
println!("{}", s.iter().collect::<String>());
63+
}
64+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub use dsu::Dsu;
2222
pub use fenwicktree::FenwickTree;
2323
pub use lazysegtree::{LazySegtree, MapMonoid};
2424
pub use math::{crt, floor_sum, inv_mod, pow_mod};
25+
pub use maxflow::{Edge, MfGraph};
2526
pub use mincostflow::MinCostFlowGraph;
2627
pub use modint::{
2728
Barrett, DefaultId, DynamicModInt, Id, Mod1000000007, Mod998244353, ModInt, ModInt1000000007,

src/maxflow.rs

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,325 @@
1+
#![allow(dead_code)]
2+
use crate::internal_queue::SimpleQueue;
3+
use crate::internal_type_traits::Integral;
4+
use std::cmp::min;
5+
use std::iter;
16

7+
impl<Cap> MfGraph<Cap>
8+
where
9+
Cap: Integral,
10+
{
11+
pub fn new(n: usize) -> MfGraph<Cap> {
12+
MfGraph {
13+
_n: n,
14+
pos: Vec::new(),
15+
g: iter::repeat_with(Vec::new).take(n).collect(),
16+
}
17+
}
18+
19+
pub fn add_edge(&mut self, from: usize, to: usize, cap: Cap) -> usize {
20+
assert!(from < self._n);
21+
assert!(to < self._n);
22+
assert!(Cap::zero() <= cap);
23+
let m = self.pos.len();
24+
self.pos.push((from, self.g[from].len()));
25+
let rev = self.g[to].len() + if from == to { 1 } else { 0 };
26+
self.g[from].push(_Edge { to, rev, cap });
27+
let rev = self.g[from].len() - 1;
28+
self.g[to].push(_Edge {
29+
to: from,
30+
rev,
31+
cap: Cap::zero(),
32+
});
33+
m
34+
}
35+
}
36+
37+
#[derive(Debug, PartialEq, Eq)]
38+
pub struct Edge<Cap: Integral> {
39+
pub from: usize,
40+
pub to: usize,
41+
pub cap: Cap,
42+
pub flow: Cap,
43+
}
44+
45+
impl<Cap> MfGraph<Cap>
46+
where
47+
Cap: Integral,
48+
{
49+
pub fn get_edge(&self, i: usize) -> Edge<Cap> {
50+
let m = self.pos.len();
51+
assert!(i < m);
52+
let _e = &self.g[self.pos[i].0][self.pos[i].1];
53+
let _re = &self.g[_e.to][_e.rev];
54+
Edge {
55+
from: self.pos[i].0,
56+
to: _e.to,
57+
cap: _e.cap + _re.cap,
58+
flow: _re.cap,
59+
}
60+
}
61+
pub fn edges(&self) -> Vec<Edge<Cap>> {
62+
let m = self.pos.len();
63+
(0..m).map(|i| self.get_edge(i)).collect()
64+
}
65+
pub fn change_edge(&mut self, i: usize, new_cap: Cap, new_flow: Cap) {
66+
let m = self.pos.len();
67+
assert!(i < m);
68+
assert!(Cap::zero() <= new_flow && new_flow <= new_cap);
69+
let (to, rev) = {
70+
let _e = &mut self.g[self.pos[i].0][self.pos[i].1];
71+
_e.cap = new_cap - new_flow;
72+
(_e.to, _e.rev)
73+
};
74+
let _re = &mut self.g[to][rev];
75+
_re.cap = new_flow;
76+
}
77+
78+
/// `s != t` must hold, otherwise it panics.
79+
pub fn flow(&mut self, s: usize, t: usize) -> Cap {
80+
self.flow_with_capacity(s, t, Cap::max_value())
81+
}
82+
/// # Parameters
83+
/// * `s != t` must hold, otherwise it panics.
84+
/// * `flow_limit >= 0`
85+
pub fn flow_with_capacity(&mut self, s: usize, t: usize, flow_limit: Cap) -> Cap {
86+
let n_ = self._n;
87+
assert!(s < n_);
88+
assert!(t < n_);
89+
// By the definition of max flow in appendix.html, this function should return 0
90+
// when the same vertices are provided. On the other hand, it is reasonable to
91+
// return infinity-like value too, which is what the original implementation
92+
// (and this implementation without the following assertion) does.
93+
// Since either return value is confusing, we'd rather deny the parameters
94+
// of the two same vertices.
95+
// For more details, see https://github.com/rust-lang-ja/ac-library-rs/pull/24#discussion_r485343451
96+
// and https://github.com/atcoder/ac-library/issues/5 .
97+
assert_ne!(s, t);
98+
// Additional constraint
99+
assert!(Cap::zero() <= flow_limit);
100+
101+
let mut calc = FlowCalculator {
102+
graph: self,
103+
s,
104+
t,
105+
flow_limit,
106+
level: vec![0; n_],
107+
iter: vec![0; n_],
108+
que: SimpleQueue::default(),
109+
};
110+
111+
let mut flow = Cap::zero();
112+
while flow < flow_limit {
113+
calc.bfs();
114+
if calc.level[t] == -1 {
115+
break;
116+
}
117+
calc.iter.iter_mut().for_each(|e| *e = 0);
118+
while flow < flow_limit {
119+
let f = calc.dfs(t, flow_limit - flow);
120+
if f == Cap::zero() {
121+
break;
122+
}
123+
flow += f;
124+
}
125+
}
126+
flow
127+
}
128+
129+
pub fn min_cut(&self, s: usize) -> Vec<bool> {
130+
let mut visited = vec![false; self._n];
131+
let mut que = SimpleQueue::default();
132+
que.push(s);
133+
while !que.empty() {
134+
let &p = que.front().unwrap();
135+
que.pop();
136+
visited[p] = true;
137+
for e in &self.g[p] {
138+
if e.cap != Cap::zero() && !visited[e.to] {
139+
visited[e.to] = true;
140+
que.push(e.to);
141+
}
142+
}
143+
}
144+
visited
145+
}
146+
}
147+
148+
struct FlowCalculator<'a, Cap> {
149+
graph: &'a mut MfGraph<Cap>,
150+
s: usize,
151+
t: usize,
152+
flow_limit: Cap,
153+
level: Vec<i32>,
154+
iter: Vec<usize>,
155+
que: SimpleQueue<usize>,
156+
}
157+
158+
impl<Cap> FlowCalculator<'_, Cap>
159+
where
160+
Cap: Integral,
161+
{
162+
fn bfs(&mut self) {
163+
self.level.iter_mut().for_each(|e| *e = -1);
164+
self.level[self.s] = 0;
165+
self.que.clear();
166+
self.que.push(self.s);
167+
while !self.que.empty() {
168+
let v = *self.que.front().unwrap();
169+
self.que.pop();
170+
for e in &self.graph.g[v] {
171+
if e.cap == Cap::zero() || self.level[e.to] >= 0 {
172+
continue;
173+
}
174+
self.level[e.to] = self.level[v] + 1;
175+
if e.to == self.t {
176+
return;
177+
}
178+
self.que.push(e.to);
179+
}
180+
}
181+
}
182+
fn dfs(&mut self, v: usize, up: Cap) -> Cap {
183+
if v == self.s {
184+
return up;
185+
}
186+
let mut res = Cap::zero();
187+
let level_v = self.level[v];
188+
for i in self.iter[v]..self.graph.g[v].len() {
189+
self.iter[v] = i;
190+
let &_Edge {
191+
to: e_to,
192+
rev: e_rev,
193+
..
194+
} = &self.graph.g[v][i];
195+
if level_v <= self.level[e_to] || self.graph.g[e_to][e_rev].cap == Cap::zero() {
196+
continue;
197+
}
198+
let d = self.dfs(e_to, min(up - res, self.graph.g[e_to][e_rev].cap));
199+
if d <= Cap::zero() {
200+
continue;
201+
}
202+
self.graph.g[v][i].cap += d;
203+
self.graph.g[e_to][e_rev].cap -= d;
204+
res += d;
205+
if res == up {
206+
break;
207+
}
208+
}
209+
self.iter[v] = self.graph.g[v].len();
210+
res
211+
}
212+
}
213+
214+
#[derive(Default)]
215+
pub struct MfGraph<Cap> {
216+
_n: usize,
217+
pos: Vec<(usize, usize)>,
218+
g: Vec<Vec<_Edge<Cap>>>,
219+
}
220+
221+
struct _Edge<Cap> {
222+
to: usize,
223+
rev: usize,
224+
cap: Cap,
225+
}
226+
227+
#[cfg(test)]
228+
mod test {
229+
use crate::{Edge, MfGraph};
230+
231+
#[test]
232+
fn test_max_flow_wikipedia() {
233+
// From https://commons.wikimedia.org/wiki/File:Min_cut.png
234+
// Under CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0/deed.en
235+
let mut graph = MfGraph::new(6);
236+
assert_eq!(graph.add_edge(0, 1, 3), 0);
237+
assert_eq!(graph.add_edge(0, 2, 3), 1);
238+
assert_eq!(graph.add_edge(1, 2, 2), 2);
239+
assert_eq!(graph.add_edge(1, 3, 3), 3);
240+
assert_eq!(graph.add_edge(2, 4, 2), 4);
241+
assert_eq!(graph.add_edge(3, 4, 4), 5);
242+
assert_eq!(graph.add_edge(3, 5, 2), 6);
243+
assert_eq!(graph.add_edge(4, 5, 3), 7);
244+
245+
assert_eq!(graph.flow(0, 5), 5);
246+
247+
let edges = graph.edges();
248+
{
249+
#[rustfmt::skip]
250+
assert_eq!(
251+
edges,
252+
vec![
253+
Edge { from: 0, to: 1, cap: 3, flow: 3 },
254+
Edge { from: 0, to: 2, cap: 3, flow: 2 },
255+
Edge { from: 1, to: 2, cap: 2, flow: 0 },
256+
Edge { from: 1, to: 3, cap: 3, flow: 3 },
257+
Edge { from: 2, to: 4, cap: 2, flow: 2 },
258+
Edge { from: 3, to: 4, cap: 4, flow: 1 },
259+
Edge { from: 3, to: 5, cap: 2, flow: 2 },
260+
Edge { from: 4, to: 5, cap: 3, flow: 3 },
261+
]
262+
);
263+
}
264+
assert_eq!(
265+
graph.min_cut(0),
266+
vec![true, false, true, false, false, false]
267+
);
268+
}
269+
270+
#[test]
271+
fn test_max_flow_wikipedia_multiple_edges() {
272+
// From https://commons.wikimedia.org/wiki/File:Min_cut.png
273+
// Under CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0/deed.en
274+
let mut graph = MfGraph::new(6);
275+
for &(u, v, c) in &[
276+
(0, 1, 3),
277+
(0, 2, 3),
278+
(1, 2, 2),
279+
(1, 3, 3),
280+
(2, 4, 2),
281+
(3, 4, 4),
282+
(3, 5, 2),
283+
(4, 5, 3),
284+
] {
285+
for _ in 0..c {
286+
graph.add_edge(u, v, 1);
287+
}
288+
}
289+
290+
assert_eq!(graph.flow(0, 5), 5);
291+
assert_eq!(
292+
graph.min_cut(0),
293+
vec![true, false, true, false, false, false]
294+
);
295+
}
296+
297+
#[test]
298+
#[allow(clippy::many_single_char_names)]
299+
fn test_max_flow_misawa() {
300+
// Originally by @MiSawa
301+
// From https://gist.github.com/MiSawa/47b1d99c372daffb6891662db1a2b686
302+
let n = 100;
303+
304+
let mut graph = MfGraph::new((n + 1) * 2 + 5);
305+
let (s, a, b, c, t) = (0, 1, 2, 3, 4);
306+
graph.add_edge(s, a, 1);
307+
graph.add_edge(s, b, 2);
308+
graph.add_edge(b, a, 2);
309+
graph.add_edge(c, t, 2);
310+
for i in 0..n {
311+
let i = 2 * i + 5;
312+
for j in 0..2 {
313+
for k in 2..4 {
314+
graph.add_edge(i + j, i + k, 3);
315+
}
316+
}
317+
}
318+
for j in 0..2 {
319+
graph.add_edge(a, 5 + j, 3);
320+
graph.add_edge(2 * n + 5 + j, c, 3);
321+
}
322+
323+
assert_eq!(graph.flow(s, t), 2);
324+
}
325+
}

0 commit comments

Comments
 (0)