ac_library/
mincostflow.rs

1use crate::internal_type_traits::Integral;
2
3#[derive(Clone, Debug)]
4pub struct MinCostFlowEdge<T> {
5    pub from: usize,
6    pub to: usize,
7    pub cap: T,
8    pub flow: T,
9    pub cost: T,
10}
11
12#[derive(Clone, Debug)]
13pub struct MinCostFlowGraph<T> {
14    pos: Vec<(usize, usize)>,
15    g: Vec<Vec<_Edge<T>>>,
16}
17
18impl<T> MinCostFlowGraph<T>
19where
20    T: Integral + std::ops::Neg<Output = T>,
21{
22    pub fn new(n: usize) -> Self {
23        Self {
24            pos: vec![],
25            g: (0..n).map(|_| vec![]).collect(),
26        }
27    }
28
29    pub fn get_edge(&self, i: usize) -> MinCostFlowEdge<T> {
30        assert!(i < self.pos.len());
31        let e = &self.g[self.pos[i].0][self.pos[i].1];
32        let re = &self.g[e.to][e.rev];
33        MinCostFlowEdge {
34            from: self.pos[i].0,
35            to: e.to,
36            cap: e.cap + re.cap,
37            flow: re.cap,
38            cost: e.cost,
39        }
40    }
41
42    pub fn edges(&self) -> Vec<MinCostFlowEdge<T>> {
43        let m = self.pos.len();
44        let mut result = vec![];
45        for i in 0..m {
46            result.push(self.get_edge(i));
47        }
48        result
49    }
50
51    pub fn add_edge(&mut self, from: usize, to: usize, cap: T, cost: T) -> usize {
52        assert!(from < self.g.len());
53        assert!(to < self.g.len());
54        assert_ne!(from, to);
55        assert!(cap >= T::zero());
56        assert!(cost >= T::zero());
57
58        self.pos.push((from, self.g[from].len()));
59
60        let rev = self.g[to].len();
61        self.g[from].push(_Edge { to, rev, cap, cost });
62
63        let rev = self.g[from].len() - 1;
64        self.g[to].push(_Edge {
65            to: from,
66            rev,
67            cap: T::zero(),
68            cost: -cost,
69        });
70
71        self.pos.len() - 1
72    }
73
74    /// Returns (maximum flow, cost)
75    pub fn flow(&mut self, source: usize, sink: usize, flow_limit: T) -> (T, T) {
76        self.slope(source, sink, flow_limit).pop().unwrap()
77    }
78
79    pub fn slope(&mut self, source: usize, sink: usize, flow_limit: T) -> Vec<(T, T)> {
80        let n = self.g.len();
81        assert!(source < n);
82        assert!(sink < n);
83        assert_ne!(source, sink);
84
85        let mut dual = vec![T::zero(); n];
86        let mut prev_v = vec![0; n];
87        let mut prev_e = vec![0; n];
88        let mut flow = T::zero();
89        let mut cost = T::zero();
90        let mut prev_cost_per_flow: Option<T> = None;
91        let mut result = vec![(flow, cost)];
92        while flow < flow_limit {
93            if !self.refine_dual(source, sink, &mut dual, &mut prev_v, &mut prev_e) {
94                break;
95            }
96
97            let mut c = flow_limit - flow;
98            let mut v = sink;
99            while v != source {
100                c = std::cmp::min(c, self.g[prev_v[v]][prev_e[v]].cap);
101                v = prev_v[v];
102            }
103
104            let mut v = sink;
105            while v != source {
106                self.g[prev_v[v]][prev_e[v]].cap -= c;
107                let rev = self.g[prev_v[v]][prev_e[v]].rev;
108                self.g[v][rev].cap += c;
109                v = prev_v[v];
110            }
111
112            let d = -dual[source];
113            flow += c;
114            cost += d * c;
115            if prev_cost_per_flow == Some(d) {
116                assert!(result.pop().is_some());
117            }
118            result.push((flow, cost));
119            prev_cost_per_flow = Some(d);
120        }
121        result
122    }
123
124    fn refine_dual(
125        &self,
126        source: usize,
127        sink: usize,
128        dual: &mut [T],
129        pv: &mut [usize],
130        pe: &mut [usize],
131    ) -> bool {
132        let n = self.g.len();
133        let mut dist = vec![T::max_value(); n];
134        let mut vis = vec![false; n];
135
136        let mut que = std::collections::BinaryHeap::new();
137        dist[source] = T::zero();
138        que.push((std::cmp::Reverse(T::zero()), source));
139        while let Some((_, v)) = que.pop() {
140            if vis[v] {
141                continue;
142            }
143            vis[v] = true;
144            if v == sink {
145                break;
146            }
147
148            for (i, e) in self.g[v].iter().enumerate() {
149                if vis[e.to] || e.cap == T::zero() {
150                    continue;
151                }
152
153                let cost = e.cost - dual[e.to] + dual[v];
154                if dist[e.to] - dist[v] > cost {
155                    dist[e.to] = dist[v] + cost;
156                    pv[e.to] = v;
157                    pe[e.to] = i;
158                    que.push((std::cmp::Reverse(dist[e.to]), e.to));
159                }
160            }
161        }
162
163        if !vis[sink] {
164            return false;
165        }
166
167        for v in 0..n {
168            if !vis[v] {
169                continue;
170            }
171            dual[v] -= dist[sink] - dist[v];
172        }
173        true
174    }
175}
176
177#[derive(Clone, Debug)]
178struct _Edge<T> {
179    to: usize,
180    rev: usize,
181    cap: T,
182    cost: T,
183}
184
185#[cfg(test)]
186mod tests {
187    use super::*;
188
189    #[test]
190    fn test_min_cost_flow() {
191        let mut graph = MinCostFlowGraph::new(4);
192        graph.add_edge(0, 1, 2, 1);
193        graph.add_edge(0, 2, 1, 2);
194        graph.add_edge(1, 2, 1, 1);
195        graph.add_edge(1, 3, 1, 3);
196        graph.add_edge(2, 3, 2, 1);
197        let (flow, cost) = graph.flow(0, 3, 2);
198        assert_eq!(flow, 2);
199        assert_eq!(cost, 6);
200    }
201
202    #[test]
203    fn same_cost_paths() {
204        // https://github.com/atcoder/ac-library/blob/300e66a7d73efe27d02f38133239711148092030/test/unittest/mincostflow_test.cpp#L83-L90
205        let mut graph = MinCostFlowGraph::new(3);
206        assert_eq!(0, graph.add_edge(0, 1, 1, 1));
207        assert_eq!(1, graph.add_edge(1, 2, 1, 0));
208        assert_eq!(2, graph.add_edge(0, 2, 2, 1));
209        let expected = [(0, 0), (3, 3)];
210        assert_eq!(expected[..], *graph.slope(0, 2, i32::MAX));
211    }
212
213    #[test]
214    fn only_one_nonzero_cost_edge() {
215        let mut graph = MinCostFlowGraph::new(3);
216        assert_eq!(0, graph.add_edge(0, 1, 1, 1));
217        assert_eq!(1, graph.add_edge(1, 2, 1, 0));
218        let expected = [(0, 0), (1, 1)];
219        assert_eq!(expected[..], *graph.slope(0, 2, i32::MAX));
220    }
221}