pub struct BipartiteMatching { /* private fields */ }
Implementations§
Source§impl BipartiteMatching
impl BipartiteMatching
pub fn new(left_size: usize, right_size: usize) -> Self
pub fn add_edge(&mut self, l: usize, r: usize)
Sourcepub fn from_edges(
left_size: usize,
right_size: usize,
lr: &[(usize, usize)],
) -> Self
pub fn from_edges( left_size: usize, right_size: usize, lr: &[(usize, usize)], ) -> Self
Examples found in repository?
More examples
crates/competitive/src/graph/dulmage_mendelsohn_decomposition.rs (line 10)
3pub fn dulmage_mendelsohn_decomposition(
4 l: usize,
5 r: usize,
6 edges: &[(usize, usize)],
7) -> Vec<(Vec<usize>, Vec<usize>)> {
8 let mut matching = vec![!0usize; l + r];
9 let mut medges: Vec<_> = edges.iter().map(|&(u, v)| (u, v + l)).collect();
10 for (u, v) in BipartiteMatching::from_edges(l, r, edges).maximum_matching() {
11 medges.push((v + l, u));
12 matching[u] = v + l;
13 matching[v + l] = u;
14 }
15 let rmedges = medges.iter().map(|&(u, v)| (v, u)).collect();
16
17 let g = DirectedSparseGraph::from_edges(l + r, medges);
18 let rg = DirectedSparseGraph::from_edges(l + r, rmedges);
19 let scc = StronglyConnectedComponent::new(&g);
20 let csize = scc.size();
21
22 let mut cmap = vec![!0usize - 1; csize];
23 let mut visited = vec![false; l + r];
24 let mut stack = vec![];
25 for u in 0..l {
26 if matching[u] == !0 && !visited[u] {
27 visited[u] = true;
28 stack.push(u);
29 while let Some(u) = stack.pop() {
30 cmap[scc[u]] = !0;
31 for a in g.adjacencies(u) {
32 if !visited[a.to] {
33 visited[a.to] = true;
34 stack.push(a.to);
35 }
36 }
37 }
38 }
39 }
40 for u in l..l + r {
41 if matching[u] == !0 && !visited[u] {
42 visited[u] = true;
43 stack.push(u);
44 while let Some(u) = stack.pop() {
45 cmap[scc[u]] = 0;
46 for a in rg.adjacencies(u) {
47 if !visited[a.to] {
48 visited[a.to] = true;
49 stack.push(a.to);
50 }
51 }
52 }
53 }
54 }
55
56 let mut nset = 1usize;
57 for v in &mut cmap {
58 if *v == !0 - 1 {
59 *v = nset;
60 nset += 1;
61 }
62 }
63 for v in &mut cmap {
64 if *v == !0 {
65 *v = nset;
66 }
67 }
68 nset += 1;
69
70 let mut groups = vec![(vec![], vec![]); nset];
71 for u in 0..l {
72 if matching[u] != !0 {
73 let c = cmap[scc[u]];
74 groups[c].0.push(u);
75 groups[c].1.push(matching[u] - l);
76 }
77 }
78 for u in 0..l {
79 if matching[u] == !0 {
80 let c = cmap[scc[u]];
81 groups[c].0.push(u);
82 }
83 }
84 for u in 0..r {
85 if matching[u + l] == !0 {
86 let c = cmap[scc[u + l]];
87 groups[c].1.push(u);
88 }
89 }
90 groups
91}
pub fn hopcroft_karp(&mut self)
Sourcepub fn kuhn_multi_start_bfs(&mut self)
pub fn kuhn_multi_start_bfs(&mut self)
Examples found in repository?
crates/competitive/src/graph/bipartite_matching.rs (line 172)
171 pub fn maximum_matching(&mut self) -> Vec<(usize, usize)> {
172 self.kuhn_multi_start_bfs();
173 self.left_match
174 .iter()
175 .enumerate()
176 .filter_map(|(l, r)| r.map(|r| (l, r)))
177 .collect()
178 }
179 pub fn minimum_edge_cover(&mut self) -> Vec<(usize, usize)> {
180 self.kuhn_multi_start_bfs();
181 let mut res = Vec::with_capacity(self.left_size + self.right_size - self.matching_size);
182 let mut left_used: Vec<_> = self.left_match.iter().map(Option::is_some).collect();
183 let mut right_used: Vec<_> = self.right_match.iter().map(Option::is_some).collect();
184 for (l, lg) in self.left_graph.iter().enumerate() {
185 if let Some(r) = self.left_match[l] {
186 res.push((l, r));
187 }
188 for &r in lg {
189 if !left_used[l] || !right_used[r] {
190 left_used[l] = true;
191 right_used[r] = true;
192 res.push((l, r));
193 }
194 }
195 }
196 res
197 }
198 fn reachable(&mut self) -> (Vec<bool>, Vec<bool>) {
199 #[derive(Clone, Copy)]
200 enum Either {
201 Left(usize),
202 Right(usize),
203 }
204 self.kuhn_multi_start_bfs();
205 let mut left_used = vec![false; self.left_size];
206 let mut right_used = vec![false; self.right_size];
207 let mut deq = VecDeque::new();
208 for (l, r) in self.left_match.iter().enumerate() {
209 if r.is_none() {
210 left_used[l] = true;
211 deq.push_back(Either::Left(l));
212 }
213 }
214 loop {
215 match deq.pop_front() {
216 Some(Either::Left(l)) => {
217 for &r in &self.left_graph[l] {
218 if self.left_match[l] != Some(r) && !right_used[r] {
219 right_used[r] = true;
220 deq.push_back(Either::Right(r));
221 }
222 }
223 }
224 Some(Either::Right(r)) => {
225 if let Some(l) = self.right_match[r] {
226 if !left_used[l] {
227 left_used[l] = true;
228 deq.push_back(Either::Left(l));
229 }
230 }
231 }
232 None => break,
233 }
234 }
235 (left_used, right_used)
236 }
Sourcepub fn maximum_matching(&mut self) -> Vec<(usize, usize)>
pub fn maximum_matching(&mut self) -> Vec<(usize, usize)>
Examples found in repository?
More examples
crates/competitive/src/graph/dulmage_mendelsohn_decomposition.rs (line 10)
3pub fn dulmage_mendelsohn_decomposition(
4 l: usize,
5 r: usize,
6 edges: &[(usize, usize)],
7) -> Vec<(Vec<usize>, Vec<usize>)> {
8 let mut matching = vec![!0usize; l + r];
9 let mut medges: Vec<_> = edges.iter().map(|&(u, v)| (u, v + l)).collect();
10 for (u, v) in BipartiteMatching::from_edges(l, r, edges).maximum_matching() {
11 medges.push((v + l, u));
12 matching[u] = v + l;
13 matching[v + l] = u;
14 }
15 let rmedges = medges.iter().map(|&(u, v)| (v, u)).collect();
16
17 let g = DirectedSparseGraph::from_edges(l + r, medges);
18 let rg = DirectedSparseGraph::from_edges(l + r, rmedges);
19 let scc = StronglyConnectedComponent::new(&g);
20 let csize = scc.size();
21
22 let mut cmap = vec![!0usize - 1; csize];
23 let mut visited = vec![false; l + r];
24 let mut stack = vec![];
25 for u in 0..l {
26 if matching[u] == !0 && !visited[u] {
27 visited[u] = true;
28 stack.push(u);
29 while let Some(u) = stack.pop() {
30 cmap[scc[u]] = !0;
31 for a in g.adjacencies(u) {
32 if !visited[a.to] {
33 visited[a.to] = true;
34 stack.push(a.to);
35 }
36 }
37 }
38 }
39 }
40 for u in l..l + r {
41 if matching[u] == !0 && !visited[u] {
42 visited[u] = true;
43 stack.push(u);
44 while let Some(u) = stack.pop() {
45 cmap[scc[u]] = 0;
46 for a in rg.adjacencies(u) {
47 if !visited[a.to] {
48 visited[a.to] = true;
49 stack.push(a.to);
50 }
51 }
52 }
53 }
54 }
55
56 let mut nset = 1usize;
57 for v in &mut cmap {
58 if *v == !0 - 1 {
59 *v = nset;
60 nset += 1;
61 }
62 }
63 for v in &mut cmap {
64 if *v == !0 {
65 *v = nset;
66 }
67 }
68 nset += 1;
69
70 let mut groups = vec![(vec![], vec![]); nset];
71 for u in 0..l {
72 if matching[u] != !0 {
73 let c = cmap[scc[u]];
74 groups[c].0.push(u);
75 groups[c].1.push(matching[u] - l);
76 }
77 }
78 for u in 0..l {
79 if matching[u] == !0 {
80 let c = cmap[scc[u]];
81 groups[c].0.push(u);
82 }
83 }
84 for u in 0..r {
85 if matching[u + l] == !0 {
86 let c = cmap[scc[u + l]];
87 groups[c].1.push(u);
88 }
89 }
90 groups
91}
pub fn minimum_edge_cover(&mut self) -> Vec<(usize, usize)>
pub fn minimum_vertex_cover(&mut self) -> (Vec<usize>, Vec<usize>)
pub fn maximum_independent_set(&mut self) -> (Vec<usize>, Vec<usize>)
Trait Implementations§
Source§impl Clone for BipartiteMatching
impl Clone for BipartiteMatching
Source§fn clone(&self) -> BipartiteMatching
fn clone(&self) -> BipartiteMatching
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moreAuto Trait Implementations§
impl Freeze for BipartiteMatching
impl RefUnwindSafe for BipartiteMatching
impl Send for BipartiteMatching
impl Sync for BipartiteMatching
impl Unpin for BipartiteMatching
impl UnwindSafe for BipartiteMatching
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more