pub struct UnionFind {
parent: Vec<usize>,
rank: Vec<u8>,
}
impl UnionFind {
pub fn new(n: usize) -> Self {
Self {
parent: (0..n).collect(),
rank: vec![0; n],
}
}
pub fn find(&mut self, mut x: usize) -> usize {
let mut root = x;
while self.parent[root] != root {
root = self.parent[root];
}
while self.parent[x] != root {
let next = self.parent[x];
self.parent[x] = root;
x = next;
}
root
}
pub fn link(&mut self, x: usize, y: usize) {
debug_assert!(self.parent[x] == x && self.parent[y] == y);
if self.rank[x] < self.rank[y] {
self.parent[x] = y;
} else {
self.parent[y] = x;
if self.rank[x] == self.rank[y] {
self.rank[x] += 1;
}
}
}
}