Skip to content

Commit

Permalink
Merge pull request #78 from qryxip/doc-for-dsu
Browse files Browse the repository at this point in the history
Update the documentation for `dsu`
  • Loading branch information
qryxip authored Mar 25, 2022
2 parents 330306f + 3ec9768 commit 16875d3
Showing 1 changed file with 121 additions and 5 deletions.
126 changes: 121 additions & 5 deletions src/dsu.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,49 @@
/// Implement (union by size) + (path compression)
/// Reference:
/// Zvi Galil and Giuseppe F. Italiano,
/// Data structures and algorithms for disjoint set union problems
//! 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_rs::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
Expand All @@ -10,13 +52,37 @@ pub struct Dsu {
}

impl Dsu {
// 0 <= size <= 10^8 is constrained.
/// 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);
Expand All @@ -32,11 +98,39 @@ impl Dsu {
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 {
Expand All @@ -45,11 +139,33 @@ impl Dsu {
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];
Expand Down

0 comments on commit 16875d3

Please sign in to comment.