提出 #45106507
ソースコード 拡げる
use dsu::*;
use proconio::{input, marker::Usize1};
fn main() {
input! {
n: usize,
m: usize,
ab: [(Usize1, Usize1); m],
};
let mut dsu = Dsu::new(n);
for (a, b) in ab {
dsu.merge(a, b);
}
let ans = dsu.groups().iter().map(|g| g.len()).max().unwrap();
println!("{}", ans);
}
//https://github.com/rust-lang-ja/ac-library-rs
pub mod dsu {
//! A Disjoint set union (DSU) with union by size and path compression.
/// A Disjoint set union (DSU) with union by size and path compression.
///
/// See: [Zvi Galil and Giuseppe F. Italiano, Data structures and algorithms for disjoint set union problems](https://core.ac.uk/download/pdf/161439519.pdf)
///
/// In the following documentation, let $n$ be the size of the DSU.
///
/// # Example
///
/// ```
/// use ac_library::Dsu;
/// use proconio::{input, source::once::OnceSource};
///
/// input! {
/// from OnceSource::from(
/// "5\n\
/// 3\n\
/// 0 1\n\
/// 2 3\n\
/// 3 4\n",
/// ),
/// n: usize,
/// abs: [(usize, usize)],
/// }
///
/// let mut dsu = Dsu::new(n);
/// for (a, b) in abs {
/// dsu.merge(a, b);
/// }
///
/// assert!(dsu.same(0, 1));
/// assert!(!dsu.same(1, 2));
/// assert!(dsu.same(2, 4));
///
/// assert_eq!(
/// dsu.groups()
/// .into_iter()
/// .map(|mut group| {
/// group.sort_unstable();
/// group
/// })
/// .collect::<Vec<_>>(),
/// [&[0, 1][..], &[2, 3, 4][..]],
/// );
/// ```
pub struct Dsu {
n: usize,
// root node: -1 * component size
// otherwise: parent
parent_or_size: Vec<i32>,
}
impl Dsu {
/// Creates a new `Dsu`.
///
/// # Constraints
///
/// - $0 \leq n \leq 10^8$
///
/// # Complexity
///
/// - $O(n)$
pub fn new(size: usize) -> Self {
Self {
n: size,
parent_or_size: vec![-1; size],
}
}
// `\textsc` does not work in KaTeX
/// Performs the Uɴɪᴏɴ operation.
///
/// # Constraints
///
/// - $0 \leq a < n$
/// - $0 \leq b < n$
///
/// # Panics
///
/// Panics if the above constraints are not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
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
}
/// Returns whether the vertices $a$ and $b$ are in the same connected component.
///
/// # Constraints
///
/// - $0 \leq a < n$
/// - $0 \leq b < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn same(&mut self, a: usize, b: usize) -> bool {
assert!(a < self.n);
assert!(b < self.n);
self.leader(a) == self.leader(b)
}
/// Performs the Fɪɴᴅ operation.
///
/// # Constraints
///
/// - $0 \leq a < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
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
}
/// Returns the size of the connected component that contains the vertex $a$.
///
/// # Constraints
///
/// - $0 \leq a < n$
///
/// # Panics
///
/// Panics if the above constraint is not satisfied.
///
/// # Complexity
///
/// - $O(\alpha(n))$ amortized
pub fn size(&mut self, a: usize) -> usize {
assert!(a < self.n);
let x = self.leader(a);
-self.parent_or_size[x] as usize
}
/// Divides the graph into connected components.
///
/// The result may not be ordered.
///
/// # Complexity
///
/// - $O(n)$
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!(d.same(0, 1));
d.merge(1, 2);
assert!(d.same(0, 2));
assert_eq!(d.size(0), 3);
assert!(!d.same(0, 3));
assert_eq!(d.groups(), vec![vec![0, 1, 2], vec![3]]);
}
}
}
提出情報
提出日時 |
|
問題 |
D - Friends |
ユーザ |
bouzuya |
言語 |
Rust (1.42.0) |
得点 |
400 |
コード長 |
6189 Byte |
結果 |
AC |
実行時間 |
42 ms |
メモリ |
21696 KiB |
ジャッジ結果
セット名 |
Sample |
All |
得点 / 配点 |
0 / 0 |
400 / 400 |
結果 |
|
|
セット名 |
テストケース |
Sample |
sample_01.txt, sample_02.txt, sample_03.txt |
All |
hand_01.txt, hand_02.txt, hand_03.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_11.txt, random_12.txt, random_13.txt, random_21.txt, random_22.txt, random_23.txt, random_24.txt, random_25.txt, random_26.txt, random_31.txt, random_32.txt, random_33.txt, random_41.txt, random_42.txt, random_43.txt, sample_01.txt, sample_02.txt, sample_03.txt |
ケース名 |
結果 |
実行時間 |
メモリ |
hand_01.txt |
AC |
39 ms |
21696 KiB |
hand_02.txt |
AC |
2 ms |
2172 KiB |
hand_03.txt |
AC |
1 ms |
2052 KiB |
random_01.txt |
AC |
39 ms |
13012 KiB |
random_02.txt |
AC |
34 ms |
19856 KiB |
random_03.txt |
AC |
38 ms |
15156 KiB |
random_04.txt |
AC |
21 ms |
12040 KiB |
random_05.txt |
AC |
42 ms |
14544 KiB |
random_06.txt |
AC |
39 ms |
16764 KiB |
random_07.txt |
AC |
31 ms |
13044 KiB |
random_08.txt |
AC |
27 ms |
18320 KiB |
random_11.txt |
AC |
24 ms |
8832 KiB |
random_12.txt |
AC |
37 ms |
13036 KiB |
random_13.txt |
AC |
29 ms |
9412 KiB |
random_21.txt |
AC |
37 ms |
13220 KiB |
random_22.txt |
AC |
35 ms |
13068 KiB |
random_23.txt |
AC |
35 ms |
13324 KiB |
random_24.txt |
AC |
39 ms |
13288 KiB |
random_25.txt |
AC |
37 ms |
13580 KiB |
random_26.txt |
AC |
36 ms |
13496 KiB |
random_31.txt |
AC |
25 ms |
6616 KiB |
random_32.txt |
AC |
23 ms |
6848 KiB |
random_33.txt |
AC |
21 ms |
6840 KiB |
random_41.txt |
AC |
42 ms |
13220 KiB |
random_42.txt |
AC |
42 ms |
13252 KiB |
random_43.txt |
AC |
42 ms |
13540 KiB |
sample_01.txt |
AC |
2 ms |
2052 KiB |
sample_02.txt |
AC |
1 ms |
2088 KiB |
sample_03.txt |
AC |
1 ms |
2032 KiB |