提出 #44018181


ソースコード 拡げる

use dsu::*;
use im_rc::HashMap;
use proconio::{input, marker::Usize1};

fn main() {
    input! {
        n: usize,
        k: usize,
        l: usize,
        pq: [(Usize1, Usize1); k],
        rs: [(Usize1, Usize1); l],
    };

    let mut dsu1 = Dsu::new(n);
    for (p, q) in pq {
        dsu1.merge(p, q);
    }

    let mut dsu2 = Dsu::new(n);
    for (r, s) in rs {
        dsu2.merge(r, s);
    }

    let mut map = HashMap::new();
    for i in 0..n {
        let key = (dsu1.leader(i), dsu2.leader(i));
        *map.entry(key).or_insert(0) += 1;
    }

    let ans = (0..n)
        .map(|i| (dsu1.leader(i), dsu2.leader(i)))
        .map(|key| map[&key])
        .collect::<Vec<usize>>();
    let mut s = String::new();
    for (i, a_i) in ans.iter().copied().enumerate() {
        s.push_str(&format!(
            "{}{}",
            a_i,
            if i == ans.len() - 1 { '\n' } else { ' ' }
        ));
    }
    print!("{}", s);
}

//https://github.com/rust-lang-ja/ac-library-rs

pub mod dsu {
    /// Implement (union by size) + (path compression)
    /// Reference:
    /// Zvi Galil and Giuseppe F. Italiano,
    /// Data structures and algorithms for disjoint set union problems
    pub struct Dsu {
        n: usize,
        // root node: -1 * component size
        // otherwise: parent
        parent_or_size: Vec<i32>,
    }

    impl Dsu {
        // 0 <= size <= 10^8 is constrained.
        pub fn new(size: usize) -> Self {
            Self {
                n: size,
                parent_or_size: vec![-1; size],
            }
        }
        pub fn merge(&mut self, a: usize, b: usize) -> usize {
            assert!(a < self.n);
            assert!(b < self.n);
            let (mut x, mut y) = (self.leader(a), self.leader(b));
            if x == y {
                return x;
            }
            if -self.parent_or_size[x] < -self.parent_or_size[y] {
                std::mem::swap(&mut x, &mut y);
            }
            self.parent_or_size[x] += self.parent_or_size[y];
            self.parent_or_size[y] = x as i32;
            x
        }

        pub fn same(&mut self, a: usize, b: usize) -> bool {
            assert!(a < self.n);
            assert!(b < self.n);
            self.leader(a) == self.leader(b)
        }
        pub fn leader(&mut self, a: usize) -> usize {
            assert!(a < self.n);
            if self.parent_or_size[a] < 0 {
                return a;
            }
            self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
            self.parent_or_size[a] as usize
        }
        pub fn size(&mut self, a: usize) -> usize {
            assert!(a < self.n);
            let x = self.leader(a);
            -self.parent_or_size[x] as usize
        }
        pub fn groups(&mut self) -> Vec<Vec<usize>> {
            let mut leader_buf = vec![0; self.n];
            let mut group_size = vec![0; self.n];
            for i in 0..self.n {
                leader_buf[i] = self.leader(i);
                group_size[leader_buf[i]] += 1;
            }
            let mut result = vec![Vec::new(); self.n];
            for i in 0..self.n {
                result[i].reserve(group_size[i]);
            }
            for i in 0..self.n {
                result[leader_buf[i]].push(i);
            }
            result
                .into_iter()
                .filter(|x| !x.is_empty())
                .collect::<Vec<Vec<usize>>>()
        }
    }

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

        #[test]
        fn dsu_works() {
            let mut d = Dsu::new(4);
            d.merge(0, 1);
            assert_eq!(d.same(0, 1), true);
            d.merge(1, 2);
            assert_eq!(d.same(0, 2), true);
            assert_eq!(d.size(0), 3);
            assert_eq!(d.same(0, 3), false);
            assert_eq!(d.groups(), vec![vec![0, 1, 2], vec![3]]);
        }
    }
}

提出情報

提出日時
問題 D - 連結
ユーザ bouzuya
言語 Rust (1.42.0)
得点 400
コード長 3903 Byte
結果 AC
実行時間 144 ms
メモリ 56384 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 400 / 400
結果
AC × 3
AC × 18
セット名 テストケース
Sample subtask0_0.txt, subtask0_1.txt, subtask0_2.txt
All subtask0_0.txt, subtask0_1.txt, subtask0_2.txt, subtask1_0.txt, subtask1_1.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask1_14.txt, subtask1_2.txt, subtask1_3.txt, subtask1_4.txt, subtask1_5.txt, subtask1_6.txt, subtask1_7.txt, subtask1_8.txt, subtask1_9.txt
ケース名 結果 実行時間 メモリ
subtask0_0.txt AC 8 ms 2032 KiB
subtask0_1.txt AC 1 ms 2032 KiB
subtask0_2.txt AC 1 ms 2040 KiB
subtask1_0.txt AC 26 ms 6292 KiB
subtask1_1.txt AC 144 ms 56384 KiB
subtask1_10.txt AC 21 ms 6536 KiB
subtask1_11.txt AC 127 ms 52252 KiB
subtask1_12.txt AC 127 ms 49948 KiB
subtask1_13.txt AC 139 ms 53804 KiB
subtask1_14.txt AC 106 ms 43092 KiB
subtask1_2.txt AC 101 ms 41884 KiB
subtask1_3.txt AC 138 ms 53632 KiB
subtask1_4.txt AC 116 ms 46016 KiB
subtask1_5.txt AC 25 ms 6676 KiB
subtask1_6.txt AC 126 ms 50308 KiB
subtask1_7.txt AC 136 ms 53436 KiB
subtask1_8.txt AC 140 ms 53924 KiB
subtask1_9.txt AC 87 ms 33592 KiB