Struct BipartiteMatching

Source
pub struct BipartiteMatching { /* private fields */ }

Implementations§

Source§

impl BipartiteMatching

Source

pub fn new(left_size: usize, right_size: usize) -> Self

Source

pub fn add_edge(&mut self, l: usize, r: usize)

Source

pub fn from_edges( left_size: usize, right_size: usize, lr: &[(usize, usize)], ) -> Self

Examples found in repository?
crates/library_checker/src/graph/bipartitematching.rs (line 38)
34pub fn bipartitematching(reader: impl Read, mut writer: impl Write) {
35    let s = read_all_unchecked(reader);
36    let mut scanner = Scanner::new(&s);
37    scan!(scanner, l, r, m, ab: [(usize, usize); m]);
38    let mut bm = BipartiteMatching::from_edges(l, r, &ab);
39    let matching = bm.maximum_matching();
40    writeln!(writer, "{}", matching.len()).ok();
41    for (x, y) in matching {
42        writeln!(writer, "{} {}", x, y).ok();
43    }
44}
More examples
Hide additional 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}
Source

pub fn hopcroft_karp(&mut self)

Source

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

pub fn maximum_matching(&mut self) -> Vec<(usize, usize)>

Examples found in repository?
crates/library_checker/src/graph/bipartitematching.rs (line 39)
34pub fn bipartitematching(reader: impl Read, mut writer: impl Write) {
35    let s = read_all_unchecked(reader);
36    let mut scanner = Scanner::new(&s);
37    scan!(scanner, l, r, m, ab: [(usize, usize); m]);
38    let mut bm = BipartiteMatching::from_edges(l, r, &ab);
39    let matching = bm.maximum_matching();
40    writeln!(writer, "{}", matching.len()).ok();
41    for (x, y) in matching {
42        writeln!(writer, "{} {}", x, y).ok();
43    }
44}
More examples
Hide additional 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}
Source

pub fn minimum_edge_cover(&mut self) -> Vec<(usize, usize)>

Source

pub fn minimum_vertex_cover(&mut self) -> (Vec<usize>, Vec<usize>)

Source

pub fn maximum_independent_set(&mut self) -> (Vec<usize>, Vec<usize>)

Trait Implementations§

Source§

impl Clone for BipartiteMatching

Source§

fn clone(&self) -> BipartiteMatching

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BipartiteMatching

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.