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 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 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}