proconlib 0.1.0

Data structures for programming contests
Documentation
pub struct UnionFind {
    parent: Vec<usize>,
    size: Vec<usize>,
}

impl UnionFind {
    pub fn new(n : usize)-> UnionFind {
        let mut par = Vec::with_capacity(n);
        for i in 0..n {
            par.push(i);
        }
        UnionFind {
            parent: par,
            size: vec![1; n]
        }
    }

    pub fn union(&mut self, l: usize, r: usize) {
        let lp = self.get_par(l);
        let rp = self.get_par(r);

        if lp != rp {
            self.parent[lp] = rp;
            self.size[rp] += self.size[lp];
        }
    }

    pub fn get_par(&mut self, tar: usize) -> usize {
        let mut par = tar;
        while self.parent[par] != par {
            par = self.parent[par];
        }
        self.parent[tar] = par;
        par
    }

    pub fn get_par_size(&mut self, tar: usize) -> usize {
        let par = self.get_par(tar);
        self.size[par]
    }

    pub fn is_same(&mut self, l: usize, r: usize) -> bool {
        let lp = self.get_par(l);
        let rp = self.get_par(r);

        lp == rp
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn union_find_test() {
        let mut union_find = UnionFind::new(10);

        union_find.union(3, 0);
        union_find.union(1, 2);
        union_find.union(4, 6);
        union_find.union(9, 5);

        union_find.union(1, 3);
        union_find.union(2, 7);
        union_find.union(8, 9);

        assert!(union_find.is_same(0, 3));
        assert!(union_find.is_same(0, 7));
        assert!(union_find.is_same(0, 7));
        assert!(union_find.is_same(5, 8));
        assert!(!union_find.is_same(0, 4));
        assert!(!union_find.is_same(6, 8));
        assert!(!union_find.is_same(1, 9));
        assert_eq!(5, union_find.get_par_size(0));
        assert_eq!(5, union_find.get_par_size(1));
        assert_eq!(2, union_find.get_par_size(4));
        assert_eq!(3, union_find.get_par_size(5));
    }
}