結果
問題 | No.1254 補強への架け橋 |
ユーザー | fukafukatani |
提出日時 | 2020-10-09 22:47:02 |
言語 | Rust (1.77.0 + proconio) |
結果 |
RE
|
実行時間 | - |
コード長 | 5,371 bytes |
コンパイル時間 | 14,640 ms |
コンパイル使用メモリ | 382,728 KB |
実行使用メモリ | 813,312 KB |
最終ジャッジ日時 | 2024-07-20 13:13:57 |
合計ジャッジ時間 | 18,291 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | RE | - |
testcase_04 | AC | 1 ms
5,376 KB |
testcase_05 | AC | 1 ms
5,376 KB |
testcase_06 | AC | 1 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | MLE | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
testcase_38 | -- | - |
testcase_39 | -- | - |
testcase_40 | -- | - |
testcase_41 | -- | - |
testcase_42 | -- | - |
testcase_43 | -- | - |
testcase_44 | -- | - |
testcase_45 | -- | - |
testcase_46 | -- | - |
testcase_47 | -- | - |
testcase_48 | -- | - |
testcase_49 | -- | - |
testcase_50 | -- | - |
testcase_51 | -- | - |
testcase_52 | -- | - |
testcase_53 | -- | - |
testcase_54 | -- | - |
testcase_55 | -- | - |
testcase_56 | -- | - |
testcase_57 | -- | - |
testcase_58 | -- | - |
testcase_59 | -- | - |
testcase_60 | -- | - |
testcase_61 | -- | - |
testcase_62 | -- | - |
testcase_63 | -- | - |
testcase_64 | -- | - |
testcase_65 | -- | - |
testcase_66 | -- | - |
testcase_67 | -- | - |
testcase_68 | -- | - |
testcase_69 | -- | - |
testcase_70 | -- | - |
testcase_71 | -- | - |
testcase_72 | -- | - |
testcase_73 | -- | - |
testcase_74 | -- | - |
testcase_75 | -- | - |
testcase_76 | -- | - |
testcase_77 | -- | - |
testcase_78 | -- | - |
testcase_79 | -- | - |
testcase_80 | -- | - |
testcase_81 | -- | - |
testcase_82 | -- | - |
testcase_83 | -- | - |
testcase_84 | -- | - |
testcase_85 | -- | - |
testcase_86 | -- | - |
testcase_87 | -- | - |
testcase_88 | -- | - |
testcase_89 | -- | - |
testcase_90 | -- | - |
testcase_91 | -- | - |
testcase_92 | -- | - |
testcase_93 | -- | - |
testcase_94 | -- | - |
testcase_95 | -- | - |
testcase_96 | -- | - |
testcase_97 | -- | - |
testcase_98 | -- | - |
testcase_99 | -- | - |
testcase_100 | -- | - |
testcase_101 | -- | - |
testcase_102 | -- | - |
testcase_103 | -- | - |
testcase_104 | -- | - |
testcase_105 | -- | - |
testcase_106 | -- | - |
testcase_107 | -- | - |
testcase_108 | -- | - |
testcase_109 | -- | - |
testcase_110 | -- | - |
testcase_111 | -- | - |
testcase_112 | -- | - |
testcase_113 | -- | - |
testcase_114 | -- | - |
testcase_115 | -- | - |
testcase_116 | -- | - |
testcase_117 | -- | - |
testcase_118 | -- | - |
testcase_119 | -- | - |
testcase_120 | -- | - |
testcase_121 | -- | - |
testcase_122 | -- | - |
testcase_123 | -- | - |
testcase_124 | -- | - |
testcase_125 | -- | - |
コンパイルメッセージ
warning: unused variable: `i` --> src/main.rs:22:9 | 22 | for i in 0..n { | ^ help: if this is intentional, prefix it with an underscore: `_i` | = note: `#[warn(unused_variables)]` on by default warning: variable does not need to be mutable --> src/main.rs:27:9 | 27 | let mut uft = UnionFindTree::new(n); | ----^^^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default warning: fields `from` and `to` are never read --> src/main.rs:157:5 | 156 | struct Edge { | ---- fields in this struct 157 | from: usize, | ^^^^ 158 | to: usize, | ^^ | = note: `Edge` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis = note: `#[warn(dead_code)]` on by default warning: method `unite` is never used --> src/main.rs:205:8 | 186 | impl UnionFindTree { | ------------------ method in this implementation ... 205 | fn unite(&mut self, index0: usize, index1: usize) -> bool { | ^^^^^
ソースコード
#![allow(unused_imports)] use std::cmp::*; use std::collections::*; use std::io::Write; use std::ops::Bound::*; #[allow(unused_macros)] macro_rules! debug { ($($e:expr),*) => { #[cfg(debug_assertions)] $({ let (e, mut err) = (stringify!($e), std::io::stderr()); writeln!(err, "{} = {:?}", e, $e).unwrap() })* }; } fn main() { let n = read::<usize>(); let mut pairs = vec![]; for i in 0..n { let v = read_vec::<usize>(); let (a, b) = (v[0] - 1, v[1] - 1); pairs.push((a, b)); } let mut uft = UnionFindTree::new(n); let mut not_used = 0; for i in 0..n { let (a, b) = pairs[i]; if uft.same(a, b) { not_used = i; break; } } let mut tree = vec![vec![]; n]; for i in 0..n { if i == not_used { continue; } let (a, b) = pairs[i]; tree[a].push(b); tree[b].push(a); } let lca = LCA::new(&tree); let (a, b) = pairs[not_used]; let lca_node = lca.lca(a, b); let mut answers = vec![(a, b)]; for &start in &[a, b] { let mut cur = start; while cur != lca_node { let parent = lca.parent[0][cur].unwrap(); answers.push((cur, parent)); cur = parent; } } // debug!(answers); let mut index_map = HashMap::new(); for i in 0..n { let (u, v) = pairs[i]; index_map.insert((u, v), i); index_map.insert((v, u), i); } println!("{}", answers.len()); for (u, v) in answers { print!("{} ", index_map[&(u, v)] + 1); } println!(""); } fn read<T: std::str::FromStr>() -> T { let mut s = String::new(); std::io::stdin().read_line(&mut s).ok(); s.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>() .split_whitespace() .map(|e| e.parse().ok().unwrap()) .collect() } struct LCA { depth: Vec<usize>, parent: Vec<Vec<Option<usize>>>, log_v: usize, } impl LCA { fn new(g: &Vec<Vec<usize>>) -> LCA { LCA::with_root(g, 0) } fn with_root(g: &Vec<Vec<usize>>, root: usize) -> LCA { let n = g.len(); let log_v = (1..).find(|i| 1usize << i > n).unwrap(); let mut lca = LCA { depth: vec![0usize; n], parent: vec![vec![None; n]; 20 + 1], // support 2 ^ 20 log_v: log_v, }; lca.dfs(root, None, 0, &g); lca.doubling(g.len()); lca } fn doubling(&mut self, n: usize) { for k in 0..self.log_v { for v in 0..n { if let Some(parent_v) = self.parent[k][v] { self.parent[k + 1][v] = self.parent[k][parent_v]; } } } } fn dfs(&mut self, cur: usize, p: Option<usize>, cur_depth: usize, g: &Vec<Vec<usize>>) { self.parent[0][cur] = p; self.depth[cur] = cur_depth; for &to in g[cur].iter() { if Some(to) == p { continue; } self.dfs(to, Some(cur), cur_depth + 1, g); } } fn lca(&self, mut u: usize, mut v: usize) -> usize { if self.depth[u] > self.depth[v] { std::mem::swap(&mut u, &mut v); } while self.depth[v] != self.depth[u] { v = self.parent[(self.depth[v] - self.depth[u]).trailing_zeros() as usize][v].unwrap(); } if u == v { return u; } for k in (0..self.parent.len()).rev() { if self.parent[k][u] != self.parent[k][v] { u = self.parent[k][u].unwrap(); v = self.parent[k][v].unwrap(); } } self.parent[0][u].unwrap() } } #[derive(Debug, Clone)] struct Edge { from: usize, to: usize, cost: i32, } impl PartialEq for Edge { fn eq(&self, other: &Edge) -> bool { self.cost == other.cost } } impl Eq for Edge {} impl Ord for Edge { fn cmp(&self, other: &Self) -> Ordering { self.cost.cmp(&other.cost) } } impl PartialOrd for Edge { fn partial_cmp(&self, other: &Edge) -> Option<Ordering> { Some(self.cost.cmp(&other.cost)) } } struct UnionFindTree { parent_or_size: Vec<isize>, } impl UnionFindTree { fn new(size: usize) -> UnionFindTree { UnionFindTree { parent_or_size: vec![-1; size], } } fn find(&self, index: usize) -> usize { let mut index = index; while self.parent_or_size[index] >= 0 { index = self.parent_or_size[index] as usize; } index } fn same(&self, x: usize, y: usize) -> bool { self.find(x) == self.find(y) } fn unite(&mut self, index0: usize, index1: usize) -> bool { let a = self.find(index0); let b = self.find(index1); if a == b { false } else { if self.parent_or_size[a] < self.parent_or_size[b] { self.parent_or_size[a] += self.parent_or_size[b]; self.parent_or_size[b] = a as isize; } else { self.parent_or_size[b] += self.parent_or_size[a]; self.parent_or_size[a] = b as isize; } true } } }