-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlca.cpp
39 lines (39 loc) · 1022 Bytes
/
lca.cpp
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
/// Name: LCA
/// Description: Lowest Common Ancestor
/// Detail:
/// Guarantee: LCA<l> preprocessLCA(
/// Dependencies: graph, dfs
/// Parent: graph
template <int l> struct LCA {
vector<array<int, l>> jump;
vector<int> depth;
LCA(int n):jump(n),depth(n,-1){}
int operator()(int a, int b) const {
if (depth[a] > depth[b])
swap(a, b);
for (auto e=l-1; e>=0; --e)
if (depth[b] - (1 << e) >= depth[a])
b = jump[b][e];
if (a == b)
return a;
for (auto e=l-1; e>=0; --e)
if (jump[a][e] != jump[b][e])
a = jump[a][e], b = jump[b][e];
return jump[a][0];
}
int dist(int a, int b) const {
return depth[a] + depth[b] - 2*depth[(*this)(a, b)];
}
void recompute(int v, int u) {
jump[v][0] = u;
for (auto e=1; e<l; ++e)
jump[v][e] = jump[jump[v][e-1]][e-1];
depth[v] = depth[u] + 1;
}
};
template <int l> LCA<l> preprocessLCA(int root) const {
auto lca = LCA<l>(size());
lca.recompute(root, root);
DFS(root, {}, {}, [&](int v, int u){ lca.recompute(u, v); }, {}, {});
return lca;
}