結果
問題 | No.1420 国勢調査 (Easy) |
ユーザー |
![]() |
提出日時 | 2021-01-29 15:44:56 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 167 ms / 2,000 ms |
コード長 | 4,558 bytes |
コンパイル時間 | 13,367 ms |
コンパイル使用メモリ | 393,568 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-27 02:58:09 |
合計ジャッジ時間 | 20,159 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 30 |
ソースコード
fn main() {let input = Input::read();assert!(matches!(input.n, 1..=100000));assert!(matches!(input.m, 1..=100000));let mut union_find = UnionFind::new(input.n);for &(a, b, y) in &input.t {assert!(a < b && b < input.n);assert!(matches!(y, 0..=0x3fffffff));if let Some(diff) = union_find.diff(a, b) {if diff != y {println!("-1");return;}} else {union_find.unite(a, b, y);}// dbg!(&union_find);}for i in union_find.construct() {println!("{}", i);}}#[derive(Debug)]struct UnionFind {n: usize,parent: Vec<usize>,diff: Vec<u32>,size: Vec<usize>,}impl UnionFind {fn new(n: usize) -> UnionFind {UnionFind {n: n,parent: (0..n).collect(),diff: vec![0; n],size: vec![1; n],}}fn root(&mut self, index: usize) -> usize {if self.parent[index] == index {index} else {let ret = self.root(self.parent[index]);self.diff[index] ^= self.diff[self.parent[index]];self.parent[index] = ret;ret}}fn diff(&mut self, index1: usize, index2: usize) -> Option<u32> {let root1 = self.root(index1);let root2 = self.root(index2);if root1 == root2 {(self.diff[index1] ^ self.diff[index2]).into()} else {None}}fn unite_root(&mut self, root1: usize, root2: usize, diff: u32) {assert_ne!(root1, root2);if self.size[root1] < self.size[root2] {self.unite_root(root2, root1, diff)} else {self.size[root1] += self.size[root2];self.size[root2] = 0;self.parent[root2] = self.parent[root1];self.diff[root2] = diff;}}fn unite(&mut self, index1: usize, index2: usize, diff: u32) {let root1 = self.root(index1);let root2 = self.root(index2);self.unite_root(root1, root2, diff ^ self.diff[index1] ^ self.diff[index2])}fn construct(&mut self) -> &Vec<u32> {for i in 0..self.n {self.root(i);}&self.diff}}#[derive(Debug)]struct Input {n: usize,m: usize,t: Vec<(usize, usize, u32)>,}impl Input {fn read() -> Input {let stdin = std::io::stdin();let (n, m) = {let mut s = String::new();stdin.read_line(&mut s).unwrap();match &split(&s).unwrap()[..] {[n, m] => (n.parse().unwrap(), m.parse().unwrap()),_ => panic!("input format error: N M"),}};let t = {let mut v = Vec::new();for i in 0..m {let (a, b) = {let mut s = String::new();stdin.read_line(&mut s).unwrap();match &split(&s).unwrap()[..] {[a, b] => (a.parse::<usize>().unwrap(), b.parse::<usize>().unwrap()),_ => panic!("input format error: A_{0} B_{0}", i + 1),}};let a = a - 1;let b = b - 1;let y = {let mut s = String::new();stdin.read_line(&mut s).unwrap();match &split(&s).unwrap()[..] {[y] => y.parse().unwrap(),_ => panic!("input format error: Y_{0}", i + 1),}};v.push((a, b, y));}v};assert_eq!(stdin.read_line(&mut String::new()).unwrap(),0,"input format error: something left");Input { n: n, m: m, t: t }}}fn split(s: &str) -> Option<Vec<&str>> {enum State {Word(usize),Space,End,}let mut state = State::Word(0);let mut ret = Vec::new();for (i, c) in s.char_indices() {let prev = match state {State::End => return None,State::Word(i) => i,State::Space => {state = State::Word(i);i}};if c == ' ' || c == '\n' {ret.push(&s[prev..i]);state = if c == ' ' { State::Space } else { State::End };}}ret.into()}