Skip to content

Commit 897c6fd

Browse files
authored
Merge pull request #12 from hotman78/master
Add dsu
2 parents 0c9f9b6 + bd8089e commit 897c6fd

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/dsu.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,89 @@
1+
/// Implement (union by size) + (path compression)
2+
/// Reference:
3+
/// Zvi Galil and Giuseppe F. Italiano,
4+
/// Data structures and algorithms for disjoint set union problems
5+
pub struct Dsu {
6+
n: usize,
7+
// root node: -1 * component size
8+
// otherwise: parent
9+
parent_or_size: Vec<i32>,
10+
}
111

12+
impl Dsu {
13+
// 0 <= size <= 10^8 is constrained.
14+
pub fn new(size: usize) -> Self {
15+
Self {
16+
n: size,
17+
parent_or_size: vec![-1; size],
18+
}
19+
}
20+
pub fn merge(&mut self, a: usize, b: usize) -> usize {
21+
assert!(a < self.n);
22+
assert!(b < self.n);
23+
let (mut x, mut y) = (self.leader(a), self.leader(b));
24+
if x == y {
25+
return x;
26+
}
27+
if -self.parent_or_size[x] < -self.parent_or_size[y] {
28+
std::mem::swap(&mut x, &mut y);
29+
}
30+
self.parent_or_size[x] += self.parent_or_size[y];
31+
self.parent_or_size[y] = x as i32;
32+
x
33+
}
34+
35+
pub fn same(&mut self, a: usize, b: usize) -> bool {
36+
assert!(a < self.n);
37+
assert!(b < self.n);
38+
self.leader(a) == self.leader(b)
39+
}
40+
pub fn leader(&mut self, a: usize) -> usize {
41+
assert!(a < self.n);
42+
if self.parent_or_size[a] < 0 {
43+
return a;
44+
}
45+
self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
46+
self.parent_or_size[a] as usize
47+
}
48+
pub fn size(&mut self, a: usize) -> usize {
49+
assert!(a < self.n);
50+
let x = self.leader(a);
51+
-self.parent_or_size[x] as usize
52+
}
53+
pub fn groups(&mut self) -> Vec<Vec<usize>> {
54+
let mut leader_buf = vec![0; self.n];
55+
let mut group_size = vec![0; self.n];
56+
for i in 0..self.n {
57+
leader_buf[i] = self.leader(i);
58+
group_size[leader_buf[i]] += 1;
59+
}
60+
let mut result = vec![Vec::new(); self.n];
61+
for i in 0..self.n {
62+
result[i].reserve(group_size[i]);
63+
}
64+
for i in 0..self.n {
65+
result[leader_buf[i]].push(i);
66+
}
67+
result
68+
.into_iter()
69+
.filter(|x| !x.is_empty())
70+
.collect::<Vec<Vec<usize>>>()
71+
}
72+
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
use super::*;
77+
78+
#[test]
79+
fn dsu_works() {
80+
let mut d = Dsu::new(4);
81+
d.merge(0, 1);
82+
assert_eq!(d.same(0, 1), true);
83+
d.merge(1, 2);
84+
assert_eq!(d.same(0, 2), true);
85+
assert_eq!(d.size(0), 3);
86+
assert_eq!(d.same(0, 3), false);
87+
assert_eq!(d.groups(), vec![vec![0, 1, 2], vec![3]]);
88+
}
89+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub(crate) mod internal_queue;
1818
pub(crate) mod internal_scc;
1919
pub(crate) mod internal_type_traits;
2020

21+
pub use dsu::Dsu;
2122
pub use fenwicktree::FenwickTree;
2223
pub use string::{
2324
lcp_array, lcp_array_arbitrary, suffix_array, suffix_array_arbitrary, suffix_array_manual,

0 commit comments

Comments
 (0)