diff options
author | mathiasmagnusson <mathiasmagnussons@gmail.com> | 2022-12-09 18:00:41 +0100 |
---|---|---|
committer | mathiasmagnusson <mathiasmagnussons@gmail.com> | 2022-12-09 18:00:41 +0100 |
commit | a1eb38bebe6ce1668c3f96489506c3b05b9fe5cb (patch) | |
tree | cccf0fd4763dba123efab7c896292dc18d1eb458 /kattis-open-almostunionfind/src/main.rs | |
parent | e41e6c8bc72e3300a0fa137f198454341bc315b1 (diff) | |
download | programming-problem-solving-a1eb38bebe6ce1668c3f96489506c3b05b9fe5cb.tar.gz |
Move stuff around
Diffstat (limited to 'kattis-open-almostunionfind/src/main.rs')
-rw-r--r-- | kattis-open-almostunionfind/src/main.rs | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/kattis-open-almostunionfind/src/main.rs b/kattis-open-almostunionfind/src/main.rs deleted file mode 100644 index 6563043..0000000 --- a/kattis-open-almostunionfind/src/main.rs +++ /dev/null @@ -1,153 +0,0 @@ -// https://open.kattis.com/problems/almostunionfind - -use std::{ - io::{stdin, Read}, - iter::once, -}; - -enum Node { - Root { count: u32, sum: u64 }, - Child(usize), - Invalid, -} - -impl Node { - fn count(&self) -> u32 { - match self { - &Root { count, .. } => count, - _ => unreachable!(), - } - } -} - -use Node::*; - -fn root(uf: &mut [Node], mut node: usize) -> usize { - let mut root = node; - while let Child(parent) = uf[root] { - root = parent - } - while let Child(parent) = uf[node] { - uf[node] = Child(root); - node = parent; - } - root -} - -fn join(uf: &mut [Node], a: usize, b: usize) { - let mut a = root(uf, a); - let mut b = root(uf, b); - - if a == b { - return; - } - - if uf[a].count() < uf[b].count() { - let tmp = a; - a = b; - b = tmp; - } - - let (b_count, b_sum) = match uf[b] { - Root { count, sum } => (count, sum), - _ => unreachable!(), - }; - match &mut uf[a] { - Root { count, sum } => { - *count += b_count; - *sum += b_sum; - } - _ => unreachable!(), - } - uf[b] = Child(a); -} - -fn mov( - uf: &mut [Node], - free_index: &mut usize, - current_index_of: &mut [usize], - a: usize, - a_val: u64, - b: usize, -) { - let a_root = root(uf, a); - let b_root = root(uf, b); - if a_root == b_root { - return; - } - match &mut uf[a_root] { - Root { count, sum } => { - *count -= 1; - *sum -= a_val; - } - _ => unreachable!(), - } - match &mut uf[b_root] { - Root { count, sum } => { - *count += 1; - *sum += a_val; - } - _ => unreachable!(), - } - uf[*free_index] = Child(b_root); - current_index_of[a_val as usize] = *free_index; - *free_index += 1; -} - -fn main() { - let mut input = String::new(); - stdin().lock().read_to_string(&mut input).unwrap(); - let mut ints = input - .trim() - .split(|c| c == ' ' || c == '\n') - .map(|i| i.parse::<usize>().unwrap()); - let mut get = || ints.next(); - - while let Some(n) = get() { - let m = get().unwrap(); - - let mut uf: Vec<Node> = (0..n + m) - .map(|i| { - if i < n { - Root { - count: 1, - sum: i as u64 + 1, - } - } else { - Invalid - } - }) - .collect(); - let mut free_index = n; - let mut current_index_of: Vec<usize> = (once(0).chain(0..n)).collect(); - - for _ in 0..m { - match get().unwrap() { - 1 => { - let (p, q) = (get().unwrap(), get().unwrap()); - join(&mut uf, current_index_of[p], current_index_of[q]); - } - 2 => { - let (p, q) = (get().unwrap(), get().unwrap()); - let (pi, qi) = (current_index_of[p], current_index_of[q]); - mov( - &mut uf, - &mut free_index, - &mut current_index_of, - pi, - p as u64, - qi, - ); - } - _ => { - let p = get().unwrap(); - let r = root(&mut uf, current_index_of[p]); - match uf[r] { - Root { count, sum } => println!("{} {}", count, sum), - _ => unreachable!(), - } - } - } - } - } -} |