forked from kaidul/Data_Structure_and_Algorithms_Library
-
Notifications
You must be signed in to change notification settings - Fork 2
/
lca.cpp
87 lines (77 loc) · 2.05 KB
/
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
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
// LCA without sparse table
int lca(int u, int v) {
if(depth[u] > depth[v]) {
swap(u, v);
}
while(depth[v] > depth[u]) {
v = parent[v];
}
// assert(depth[v] == depth[u]);
while(u != v) {
u = parent[u], v = parent[v];
}
// assert(u == v);
return u;
}
//LCA using sparse table
//Complexity: O(NlgN, lgN)
#define Max 100005
int depth[Max];
int table[Max][22]; // sparse table. there will be n rows for n nodes and logn columns for every node. pre-processing complexity O(nlogn) and Query complexity logn. table[i][j] holds 2^j th parent of ith node.
int parent[Max];
vector <int> adj[Max];
void dfs(int from, int u, int dep) {
parent[u] = from;
depth[u] = dep;
for(int i = 0; i < (int)adj[u].size(); i++) {
int v = adj[u][i];
if(v == from) continue;
dfs(u, v, dep + 1);
}
}
void lcaInit(int N) {
memset(table, -1, sizeof table);
for(int i = 0; i < N; i++) {
table[i][0] = parent[i];
}
for (int j = 1; (1 << j) < N; j++) {
for(int i = 0; i < N; i++) {
if (table[i][j - 1] != -1) {
table[i][j] = table[table[i][j - 1]][j - 1];
}
}
}
}
int lcaQuery(int p, int q) {
if(depth[p] < depth[q]) {
swap(p, q);
}
// building log's value
int log = 1;
while(true) {
int next = log + 1;
if((1 << next) > depth[p]) break;
log++;
}
// uplifting p at the same level of q
for(int i = log; i >= 0; i--) {
if (depth[p] - (1 << i) >= depth[q]) {
p = table[p][i];
}
}
if (p == q) return p;
// uplifting p and q untill both of their parents are same and we're in root
for(int i = log; i >= 0; i--) {
if (table[p][i] != -1 and table[p][i] != table[q][i]) {
p = table[p][i];
q = table[q][i];
}
}
// when p and q are in the same level, return one of their parent
return parent[p];
}
/*
dfs(0, 0, 0);
lcaInit(n);
println(lcaQuery(u, v));
*/