Skip to content

Commit 5bc4228

Browse files
committed
Added dsu
1 parent 297cf39 commit 5bc4228

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

src/dsu.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,68 @@
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+
pub fn new(n: usize) -> Self {
14+
Self {
15+
n: n,
16+
parent_or_size: vec![-1; n],
17+
}
18+
}
19+
pub fn merge(&mut self, a: usize, b: usize) -> usize {
20+
assert!(a < self.n);
21+
assert!(b < self.n);
22+
let (mut x, mut y) = (self.leader(a), self.leader(b));
23+
if x == y {
24+
return x;
25+
}
26+
if -self.parent_or_size[x] < -self.parent_or_size[y] {
27+
std::mem::swap(&mut x, &mut y);
28+
}
29+
self.parent_or_size[x] += self.parent_or_size[y];
30+
self.parent_or_size[y] = x as i32;
31+
return x;
32+
}
33+
34+
pub fn same(&mut self, a: usize, b: usize) -> bool {
35+
assert!(a < self.n);
36+
assert!(b < self.n);
37+
return self.leader(a) == self.leader(b);
38+
}
39+
pub fn leader(&mut self, a: usize) -> usize {
40+
assert!(a < self.n);
41+
if self.parent_or_size[a] < 0 {
42+
return a;
43+
}
44+
self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
45+
self.parent_or_size[a] as usize
46+
}
47+
pub fn size(&mut self, a: usize) -> usize {
48+
assert!(a < self.n);
49+
let x = self.leader(a);
50+
-self.parent_or_size[x] as usize
51+
}
52+
}
53+
54+
#[cfg(test)]
55+
mod tests {
56+
use super::*;
57+
58+
#[test]
59+
fn dsu_works() {
60+
let mut d = Dsu::new(4);
61+
d.merge(0, 1);
62+
assert_eq!(d.same(0, 1), true);
63+
d.merge(1, 2);
64+
assert_eq!(d.same(0, 2), true);
65+
assert_eq!(d.size(0), 3);
66+
assert_eq!(d.same(0, 3), false);
67+
}
68+
}

0 commit comments

Comments
 (0)