Submission #28636647


Source Code Expand

use proconio::{input, marker::Usize1};

fn parent_doubling(p: &[usize]) -> Vec<Vec<usize>> {
    let n = p.len();
    let k_len = p.len().next_power_of_two().trailing_zeros() as usize;
    let mut res = vec![vec![n; n]; k_len];
    for (i, p_i) in p.iter().copied().enumerate() {
        res[0][i] = p_i;
    }
    for k in 0..k_len - 1 {
        for i in 0..p.len() {
            if res[k][i] == n {
                res[k + 1][i] = n;
            } else {
                res[k + 1][i] = res[k][res[k][i]];
            }
        }
    }
    res
}

fn lca_by_doubling(depth: &[usize], parent: &[Vec<usize>], u: usize, v: usize) -> usize {
    let k_len = parent.len();
    // u と v の深さを揃える
    let (mut u, mut v) = if depth[u] > depth[v] { (v, u) } else { (u, v) };
    for k in 0..k_len {
        if (((depth[v] - depth[u]) >> k) & 1) == 1 {
            v = parent[k][v];
        }
    }
    if u == v {
        return u;
    }
    // 二分探索する
    for k in (0..k_len).rev() {
        if parent[k][u] != parent[k][v] {
            u = parent[k][u];
            v = parent[k][v];
        }
    }
    assert_eq!(parent[0][u], parent[0][v]);
    parent[0][u]
}

fn depth_dfs(edges: &[Vec<(usize, usize)>], depth: &mut Vec<usize>, u: usize, p: usize, l: usize) {
    depth[u] = l;
    for (v, _) in edges[u].iter().copied() {
        if v == p {
            continue;
        }
        depth_dfs(edges, depth, v, u, l + 1);
    }
}

fn depth(e: &[Vec<(usize, usize)>], root: usize) -> Vec<usize> {
    let mut res = vec![0; e.len()];
    depth_dfs(&e, &mut res, root, root, 0);
    res
}

fn dist_dfs(edges: &[Vec<(usize, usize)>], dist: &mut Vec<usize>, u: usize, p: usize, l: usize) {
    dist[u] = l;
    for (v, w) in edges[u].iter().copied() {
        if v == p {
            continue;
        }
        dist_dfs(edges, dist, v, u, l + w);
    }
}

fn dist(e: &[Vec<(usize, usize)>], root: usize) -> Vec<usize> {
    let mut res = vec![0; e.len()];
    dist_dfs(&e, &mut res, root, root, 0);
    res
}

fn parent_dfs(edges: &[Vec<(usize, usize)>], parent: &mut Vec<usize>, u: usize, p: usize) {
    parent[u] = p;
    for (v, _) in edges[u].iter().copied() {
        if v == p {
            continue;
        }
        parent_dfs(edges, parent, v, u);
    }
}

fn parent(e: &[Vec<(usize, usize)>], root: usize) -> Vec<usize> {
    let mut res = vec![e.len(); e.len()];
    parent_dfs(&e, &mut res, root, e.len());
    res
}

fn adjacency_list(n: usize, uvw: &[(usize, usize, usize)]) -> Vec<Vec<(usize, usize)>> {
    let mut e = vec![vec![]; n];
    for (u, v, w) in uvw.iter().copied() {
        e[u].push((v, w));
        e[v].push((u, w));
    }
    e
}

fn main() {
    input! {
        n: usize,
        x: usize,
        abc: [(Usize1, Usize1, usize); n - 1],
    };

    let e = adjacency_list(n, &abc);
    let p = parent(&e, 0);
    let d = depth(&e, 0);
    let dist = dist(&e, 0);
    let pd = parent_doubling(&p);
    for u in 0..n {
        for v in u + 1..n {
            let lca = lca_by_doubling(&d, &pd, u, v);
            let l = dist[u] + dist[v] - dist[lca] * 2;
            if l == x {
                println!("Yes");
                return;
            }
        }
    }
    println!("No");
}

Submission Info

Submission Time
Task H - Shortest Path
User bouzuya
Language Rust (1.42.0)
Score 6
Code Size 3244 Byte
Status AC
Exec Time 423 ms
Memory 3060 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 6 / 6
Status
AC × 3
AC × 27
Set Name Test Cases
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 02_path_00.txt, 02_path_01.txt, 02_path_02.txt, 02_path_03.txt, 02_path_04.txt, 03_star_00.txt, 03_star_01.txt, 03_star_02.txt, 03_star_03.txt, 03_star_04.txt, 04_path_c_max_00.txt, 04_path_c_max_01.txt, 04_path_c_max_02.txt, 04_path_c_max_03.txt
Case Name Status Exec Time Memory
00_sample_00.txt AC 8 ms 2076 KiB
00_sample_01.txt AC 3 ms 2032 KiB
00_sample_02.txt AC 3 ms 2084 KiB
01_random_00.txt AC 331 ms 2796 KiB
01_random_01.txt AC 112 ms 2820 KiB
01_random_02.txt AC 328 ms 2856 KiB
01_random_03.txt AC 31 ms 2832 KiB
01_random_04.txt AC 321 ms 2684 KiB
01_random_05.txt AC 215 ms 2684 KiB
01_random_06.txt AC 319 ms 2864 KiB
01_random_07.txt AC 67 ms 2776 KiB
01_random_08.txt AC 335 ms 2864 KiB
01_random_09.txt AC 285 ms 2824 KiB
02_path_00.txt AC 422 ms 2856 KiB
02_path_01.txt AC 59 ms 2784 KiB
02_path_02.txt AC 423 ms 2968 KiB
02_path_03.txt AC 285 ms 2904 KiB
02_path_04.txt AC 389 ms 2984 KiB
03_star_00.txt AC 169 ms 2524 KiB
03_star_01.txt AC 19 ms 2496 KiB
03_star_02.txt AC 170 ms 2608 KiB
03_star_03.txt AC 9 ms 2480 KiB
03_star_04.txt AC 174 ms 2608 KiB
04_path_c_max_00.txt AC 421 ms 2820 KiB
04_path_c_max_01.txt AC 241 ms 2860 KiB
04_path_c_max_02.txt AC 415 ms 3060 KiB
04_path_c_max_03.txt AC 55 ms 2964 KiB