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