結果
| 問題 |
No.898 tri-βutree
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-01-03 23:01:19 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 666 ms / 4,000 ms |
| コード長 | 5,686 bytes |
| コンパイル時間 | 15,343 ms |
| コンパイル使用メモリ | 379,040 KB |
| 実行使用メモリ | 53,504 KB |
| 最終ジャッジ日時 | 2024-11-08 23:18:36 |
| 合計ジャッジ時間 | 26,641 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 |
ソースコード
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
($($r:tt)*) => {
let stdin = std::io::stdin();
let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
let mut next = move || -> String{
bytes
.by_ref()
.map(|r|r.unwrap() as char)
.skip_while(|c|c.is_whitespace())
.take_while(|c|!c.is_whitespace())
.collect()
};
input_inner!{next, $($r)*}
};
}
macro_rules! input_inner {
($next:expr) => {};
($next:expr, ) => {};
($next:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($next, $t);
input_inner!{$next $($r)*}
};
}
macro_rules! read_value {
($next:expr, ( $($t:tt),* )) => {
( $(read_value!($next, $t)),* )
};
($next:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
};
($next:expr, chars) => {
read_value!($next, String).chars().collect::<Vec<char>>()
};
($next:expr, usize1) => {
read_value!($next, usize) - 1
};
($next:expr, [ $t:tt ]) => {{
let len = read_value!($next, usize);
(0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
}};
($next:expr, $t:ty) => {
$next().parse::<$t>().expect("Parse error")
};
}
#[allow(unused)]
macro_rules! debug {
($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}
/// Lowest Common Ancestor. Call lca(x, y) to get the lca of them.
/// Many-rooted version.
/// Verified by: https://yukicoder.me/submissions/413634
pub struct LowestCommonAncestor {
n: usize,
bn: usize,
parent: Vec<usize>, // r is root <=> parent[r] = r
dep: Vec<usize>,
lca_tbl: Vec<Vec<usize>>
}
impl LowestCommonAncestor {
fn dfs(&mut self, edges: &[Vec<usize>], v: usize, par: usize, d: usize) {
self.parent[v] = par;
self.dep[v] = d;
for &u in edges[v].iter() {
if u != par {
self.dfs(edges, u, v, d + 1);
}
}
}
fn lca_init(&mut self) {
let n = self.n;
for v in 0 .. n {
self.lca_tbl[v] = vec![0; self.bn + 1];
self.lca_tbl[v][0] = self.parent[v];
}
for i in 1 .. self.bn + 1 {
for v in 0 .. n {
self.lca_tbl[v][i] =
self.lca_tbl[self.lca_tbl[v][i - 1]][i - 1];
}
}
}
pub fn lca(&self, mut x: usize, mut y: usize) -> usize {
let dx = self.dep[x];
let mut dy = self.dep[y];
if dx > dy {
return self.lca(y, x);
}
for l in (0 .. self.bn + 1).rev() {
if dy - dx >= 1 << l {
y = self.lca_tbl[y][l];
dy -= 1 << l;
}
}
assert_eq!(dx, dy);
if x == y {
return x;
}
for l in (0 .. self.bn + 1).rev() {
if self.lca_tbl[x][l] != self.lca_tbl[y][l] {
x = self.lca_tbl[x][l];
y = self.lca_tbl[y][l];
}
}
self.lca_tbl[x][0]
}
#[allow(unused)]
pub fn depth(&self, a: usize) -> usize {
self.dep[a]
}
#[allow(unused)]
pub fn parent(&self, a: usize) -> usize {
self.parent[a]
}
pub fn new(edges: &[Vec<usize>], roots: &[usize]) -> Self {
let n = edges.len();
let bn = (n.next_power_of_two() - 1).count_ones() as usize;
let mut ret = LowestCommonAncestor {
n: n, bn: bn, parent: vec![0; n], dep: vec![0; n],
lca_tbl: vec![Vec::new(); n] };
for &r in roots {
ret.dfs(edges, r, r, 0);
}
ret.lca_init();
ret
}
}
fn dfs(g: &[Vec<(usize, i64)>], v: usize, par: usize, dep: &mut [i64], d: i64) {
dep[v] = d;
for &(w, c) in &g[v] {
if w == par { continue; }
dfs(g, w, v, dep, d + c);
}
}
fn solve() {
let out = std::io::stdout();
let mut out = BufWriter::new(out.lock());
macro_rules! puts {
($($format:tt)*) => (write!(out,$($format)*).unwrap());
}
input! {
n: usize,
uvw: [(usize, usize, i64); n - 1],
xyz: [(usize, usize, usize)],
}
let mut g = vec![vec![]; n];
let mut gw = vec![vec![]; n];
for &(u, v, w) in &uvw {
g[u].push(v);
g[v].push(u);
gw[u].push((v, w));
gw[v].push((u, w));
}
let mut dep = vec![0; n];
dfs(&gw, 0, n, &mut dep, 0);
let lca = LowestCommonAncestor::new(&g, &[0]);
for &(x, y, z) in &xyz {
let l0 = lca.lca(x, y);
let l1 = lca.lca(x, z);
let l2 = lca.lca(y, z);
let l = lca.lca(l0, z);
let dsum = dep[x] + dep[y] + dep[z];
let ans = if l0 != l {
dsum - dep[l0] - 2 * dep[l]
} else if l1 != l {
dsum - dep[l1] - 2 * dep[l]
} else if l2 != l {
dsum - dep[l2] - 2 * dep[l]
} else {
dsum - 3 * dep[l]
};
puts!("{}\n", ans);
}
debugln!("dep = {:?}", dep);
}
fn main() {
// In order to avoid potential stack overflow, spawn a new thread.
let stack_size = 104_857_600; // 100 MB
let thd = std::thread::Builder::new().stack_size(stack_size);
thd.spawn(|| solve()).unwrap().join().unwrap();
}