1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
use std::collections::VecDeque; const MAX_PARENT: usize = 1 << 50; pub struct LowestCommonAncestor { parent: Vec<Vec<usize>>, depth: Vec<usize>, log_v: usize, } impl LowestCommonAncestor { pub fn new(graph: &Vec<Vec<usize>>) -> Self { let num_v = graph.len(); let root = 0; let mut depth = vec![0; num_v]; let mut log_v = 1; let mut i = 1; while i <= num_v { i *= 2; log_v += 1; } let mut parent: Vec<Vec<usize>> = vec![vec![0; num_v]; log_v]; let mut depth_vis = vec![false; num_v]; let mut stack = VecDeque::new(); stack.push_front(root); parent[0][root] = MAX_PARENT; depth[root] = 0; depth_vis[root] = true; while !stack.is_empty() { let v = stack.pop_front().unwrap(); stack.push_front(v); for &u in &graph[v] { if depth_vis[u] { continue; } parent[0][u] = v; depth[u] = depth[v] + 1; depth_vis[u] = true; stack.push_front(u); } let head = stack.pop_front().unwrap(); if head != v { stack.push_front(head); } } for k in 0..(log_v - 1) { for u in 0..num_v { parent[k + 1][u] = if parent[k][u] == MAX_PARENT { MAX_PARENT } else { parent[k][parent[k][u]] }; } } LowestCommonAncestor { parent: parent, depth: depth, log_v: log_v, } } pub fn get_lca(&self, u: usize, v: usize) -> usize { let (mut u, mut v) = if self.depth[u] <= self.depth[v] { (u, v) } else { (v, u) }; for k in 0..self.log_v { if ((self.depth[v] - self.depth[u]) & (1 << k)) != 0 { v = self.parent[k][v]; } } if u == v { return u; } for k in (0..self.log_v).rev() { if self.parent[k][u] != self.parent[k][v] { u = self.parent[k][u]; v = self.parent[k][v]; } } return self.parent[0][u]; } pub fn get_dist(&self, u: usize, v: usize) -> usize { let lca = self.get_lca(u, v); self.depth[u] + self.depth[v] - self.depth[lca] * 2 } } #[cfg(test)] mod tests { use super::*; use crate::utils::test_helper::Tester; #[test] fn solve_grl_5_c() { let tester = Tester::new("./assets/GRL_5_C/in/", "./assets/GRL_5_C/out/"); tester.test_solution(|sc| { let n: usize = sc.read(); let mut graph = (0..n).map(|_| Vec::new()).collect::<Vec<_>>(); for i in 0..n { let k = sc.read(); for _ in 0..k { let c: usize = sc.read(); graph[i].push(c); graph[c].push(i); } } let lca = LowestCommonAncestor::new(&graph); let q: usize = sc.read(); for _ in 0..q { let u: usize = sc.read(); let v: usize = sc.read(); let ans = lca.get_lca(u, v); sc.write(format!("{}\n", ans)); } }); } }