Function nekolib::graph::dinic

source ·
pub fn dinic<V, W, R, F>(
    n: usize,
    s: V,
    t: V,
    vs: impl Iterator<Item = V> + Clone,
    zero: W,
    index: impl Fn(&V) -> usize + Copy,
    delta: impl Fn(&V) -> F + Copy,
    rev: impl Fn(&V, &R) -> Rc<RefCell<W>> + Copy
) -> Wwhere
    V: Clone,
    W: Ord + Clone + AddAssign + SubAssign,
    R: Clone,
    F: Iterator<Item = (V, Rc<RefCell<W>>, R)>,
Expand description

Dinic 法に基づく最大流。

Idea

todo!()

Complexity

O(V2E)O(|V|^2|E|) 時間。

辺容量が整数のとき、多くのパラメータによって bound できることが知られている。 以下の条件は、高々定数個の例外があってもよい。

  • 最大流を FF として O(FE)O(F|E|) 時間。
  • 辺容量が高々 kk のとき O(kE3/2)O(k\,|E|^{3/2}) 時間。
  • 辺容量が高々 kk で多重辺がないとき O(kV2/3E)O(k\,|V|^{2/3}|E|) 時間。
  • 各頂点を通れるフロー量が高々 kk のとき O(kV1/2E)O(k\,|V|^{1/2}|E|) 時間。
    • kmaxvmin{eδ+(v)ue,eδ(v)ue}k \ge \max_v \min\{\sum_{e\in\delta^+(v)} u_e, \sum_{e\in\delta^-(v)} u_e\}.
    • 二部マッチングであれば k=1k = 1 であり、O(V1/2E)O(|V|^{1/2}|E|) 時間。

Examples

次のようなグラフを考える。 Wikipedia にある例である。

      10           4       10
 +--------> [1] ----> [3] -------+
 |           | \       ^ 4       |
 |           |  \  8   |         v
[0]        2 |   \--> [4] ----> [5]
 |           |         ^   10
 |    10     v     9   |
 +--------> [2] -------+

流れるフローは次の通りで、1919 である。

  • (0,1,3,5)(0, 1, 3, 5)44
  • (0,1,4,5)(0, 1, 4, 5)66
  • (0,2,4,5)(0, 2, 4, 5)44
  • (0,2,4,3,5)(0, 2, 4, 3, 5)55
use std::cell::RefCell;
use std::rc::Rc;

use nekolib::graph::dinic;

let es = vec![
    vec![(1, 10), (2, 10)],       // 0
    vec![(2, 2), (3, 4), (4, 8)], // 1
    vec![(4, 9)],                 // 2
    vec![(5, 10)],                // 3
    vec![(3, 6), (5, 10)],        // 4
    vec![],                       // 5
];
let n = es.len();
let g = {
    let mut g = vec![vec![]; 6]; // [from]: [(to, capacity, rev), ...]
    for from in 0..n {
        for &(to, capacity) in &es[from] {
            let from_len = g[from].len();
            let to_len = g[to].len();
            g[from].push((to, Rc::new(RefCell::new(capacity)), to_len));
            g[to].push((from, Rc::new(RefCell::new(0)), from_len));
        }
    }
    g
};

let index = |&v: &usize| v;
let delta = |&v: &usize| g[v].iter().map(|&(nv, ref w, r)| (nv, w.clone(), r));
let rev = |&nv: &usize, &r: &usize| g[nv][r].1.clone();

let s = 0;
let t = n - 1;
let max_flow = dinic(n, s, t, 0..n, 0, index, delta, rev);
assert_eq!(max_flow, 19);

References