use push_relabel::PushRelabel;
use std::time::Instant;
fn build_and_run(n: usize, edges: &[(usize, usize, i64, i64)], s: usize, t: usize) {
let mut pr = PushRelabel::new(n);
for &(u, v, cap, rcap) in edges {
pr.add_edge(u, v, cap, rcap);
}
let start = Instant::now();
let flow = pr.max_flow(s, t);
let duration = start.elapsed();
println!(
"n={}, m={} → flow={} (took {:?})",
n,
edges.len(),
flow,
duration
);
}
fn main() {
let w = 100;
let h = 100;
let s = w * h;
let t = s + 1;
let n = t + 1;
let mut edges = Vec::with_capacity(w * h * 2 + w * 2);
for c in 0..w {
edges.push((s, c, 1, 0));
}
for c in 0..w {
edges.push(((h - 1) * w + c, t, 1, 0));
}
for r in 0..h {
for c in 0..w {
let u = r * w + c;
if r + 1 < h {
edges.push((u, (r + 1) * w + c, 1, 0));
}
if c + 1 < w {
edges.push((u, r * w + (c + 1), 1, 0));
}
}
}
build_and_run(n, &edges, s, t);
let layers = 50;
let width = 100;
let mut next_id = 1;
let mut layers_vec = vec![vec![0]]; for _ in 1..layers {
let layer: Vec<usize> = (0..width)
.map(|_| {
let id = next_id;
next_id += 1;
id
})
.collect();
layers_vec.push(layer);
}
let sink = next_id;
let n = sink + 1;
let mut edges = Vec::with_capacity((layers - 1) * width * width + width);
for l in 0..(layers - 1) {
for &u in &layers_vec[l] {
for &v in &layers_vec[l + 1] {
edges.push((u, v, 1, 0));
}
}
}
for &u in &layers_vec[layers - 1] {
edges.push((u, sink, 1, 0));
}
build_and_run(n, &edges, 0, sink);
let n = 500;
let mut edges = Vec::new();
for u in 0..n {
for v in (u + 1)..n {
if (u ^ v) % 2 == 0 {
edges.push((u, v, 1, 0));
}
}
}
build_and_run(n, &edges, 0, n - 1);
let left = 12000;
let right = 12000;
let source = 0;
let mut next = 1;
let left_ids: Vec<usize> = (0..left)
.map(|_| {
let id = next;
next += 1;
id
})
.collect();
let right_ids: Vec<usize> = (0..right)
.map(|_| {
let id = next;
next += 1;
id
})
.collect();
let sink = next;
let n = sink + 1;
let mut edges = Vec::with_capacity(left * right + left + right);
for &u in &left_ids {
edges.push((source, u, 1, 0));
}
for &u in &left_ids {
for &v in &right_ids {
edges.push((u, v, 1, 0));
}
}
for &v in &right_ids {
edges.push((v, sink, 1, 0));
}
build_and_run(n, &edges, source, sink);
let leaves = 100_000;
let sink = 1;
let source = 0;
let mut edges = Vec::with_capacity(leaves * 2 + 1);
edges.push((source, sink, 1, 0));
for i in 2..(2 + leaves) {
edges.push((source, i, 1, 0));
edges.push((i, source, 0, 0));
}
let n = 2 + leaves;
build_and_run(n, &edges, source, sink);
}