competitive/graph/
maximum_flow.rs1use super::{BidirectionalSparseGraph, Bounded, Zero};
2use std::{
3 collections::VecDeque,
4 ops::{Add, AddAssign, Sub, SubAssign},
5};
6
7#[derive(Debug, Clone)]
8pub struct DinicBuilder<C> {
9 vsize: usize,
10 edges: Vec<(usize, usize)>,
11 capacities: Vec<C>,
12}
13impl<C> DinicBuilder<C> {
14 pub fn new(vsize: usize, esize_expect: usize) -> Self {
15 Self {
16 vsize,
17 edges: Vec::with_capacity(esize_expect),
18 capacities: Vec::with_capacity(esize_expect * 2),
19 }
20 }
21 pub fn add_edge(&mut self, from: usize, to: usize, cap: C)
22 where
23 C: Zero + PartialOrd,
24 {
25 self.edges.push((from, to));
26 assert!(cap >= C::zero());
27 self.capacities.push(cap);
28 self.capacities.push(C::zero());
29 }
30 pub fn gen_graph(&mut self) -> BidirectionalSparseGraph {
31 let edges = std::mem::take(&mut self.edges);
32 BidirectionalSparseGraph::from_edges(self.vsize, edges)
33 }
34 pub fn build(self, graph: &BidirectionalSparseGraph) -> Dinic<'_, C> {
35 let DinicBuilder {
36 vsize, capacities, ..
37 } = self;
38 Dinic {
39 graph,
40 capacities,
41 iter: Vec::with_capacity(vsize),
42 level: Vec::with_capacity(vsize),
43 deq: VecDeque::with_capacity(vsize),
44 }
45 }
46}
47impl<C> Extend<(usize, usize, C)> for DinicBuilder<C>
48where
49 C: Zero + PartialOrd,
50{
51 fn extend<I: IntoIterator<Item = (usize, usize, C)>>(&mut self, iter: I) {
52 for (from, to, cap) in iter {
53 self.add_edge(from, to, cap)
54 }
55 }
56}
57
58#[derive(Debug, Clone)]
59pub struct Dinic<'a, C> {
60 graph: &'a BidirectionalSparseGraph,
61 capacities: Vec<C>,
62 iter: Vec<usize>,
63 level: Vec<usize>,
64 deq: VecDeque<usize>,
65}
66impl<'a, C> Dinic<'a, C>
67where
68 C: Copy + Zero + Ord + Bounded + Add<Output = C> + Sub<Output = C> + AddAssign + SubAssign,
69{
70 pub fn builder(vsize: usize, esize_expect: usize) -> DinicBuilder<C> {
71 DinicBuilder::new(vsize, esize_expect)
72 }
73 fn bfs(&mut self, s: usize, t: usize) -> bool {
74 self.level.clear();
75 self.level.resize(self.graph.vertices_size(), usize::MAX);
76 self.level[s] = 0;
77 self.deq.clear();
78 self.deq.push_back(s);
79 while let Some(u) = self.deq.pop_front() {
80 for a in self.graph.adjacencies(u) {
81 if self.capacities[a.id] > C::zero() && self.level[a.to] == usize::MAX {
82 self.level[a.to] = self.level[u] + 1;
83 if a.to == t {
84 return false;
85 }
86 self.deq.push_back(a.to);
87 }
88 }
89 }
90 self.level[t] == usize::MAX
91 }
92 fn dfs(&mut self, s: usize, u: usize, upper: C) -> C {
93 if u == s {
94 return upper;
95 }
96 let mut res = C::zero();
97 for a in self.graph.adjacencies(u).skip(self.iter[u]) {
98 if self.level[u] > self.level[a.to] && self.capacities[a.id ^ 1] > C::zero() {
99 let d = self.dfs(s, a.to, (upper - res).min(self.capacities[a.id ^ 1]));
100 if d > C::zero() {
101 self.capacities[a.id ^ 1] -= d;
102 self.capacities[a.id] += d;
103 res += d;
104 if upper == res {
105 break;
106 }
107 }
108 }
109 self.iter[u] += 1;
110 }
111 res
112 }
113 pub fn maximum_flow_limited(&mut self, s: usize, t: usize, limit: C) -> C {
114 let mut flow = C::zero();
115 while flow < limit {
116 if self.bfs(s, t) {
117 break;
118 }
119 self.iter.clear();
120 self.iter.resize(self.graph.vertices_size(), 0);
121 while flow < limit {
122 let f = self.dfs(s, t, limit - flow);
123 if f == C::zero() {
124 break;
125 }
126 flow += f;
127 }
128 }
129 flow
130 }
131 pub fn maximum_flow(&mut self, s: usize, t: usize) -> C {
132 self.maximum_flow_limited(s, t, C::maximum())
133 }
134 pub fn minimum_cut(&mut self, s: usize) -> Vec<bool> {
135 let mut visited = vec![false; self.graph.vertices_size()];
136 visited[s] = true;
137 self.deq.clear();
138 self.deq.push_back(s);
139 while let Some(u) = self.deq.pop_front() {
140 for a in self.graph.adjacencies(u) {
141 if self.capacities[a.id] > C::zero() && !visited[a.to] {
142 visited[a.to] = true;
143 self.deq.push_back(a.to);
144 }
145 }
146 }
147 visited
148 }
149 pub fn get_flow(&self, eid: usize) -> C {
150 self.capacities[eid * 2 + 1]
151 }
152 pub fn change_edge(&mut self, eid: usize, cap: C, flow: C) {
153 assert!(flow <= cap);
154 self.capacities[eid * 2] = cap - flow;
155 self.capacities[eid * 2 + 1] = flow;
156 }
157}