Skip to content

Commit 981edbb

Browse files
committed
Added LCA with binary lifting in trees
1 parent 9fb7e13 commit 981edbb

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Finding LCA in a tree using binary lifting
2+
// Pre processing TC: O(nlogn)
3+
// TC for finding LCA per query: O(logn)
4+
5+
#include <bits/stdc++.h>
6+
using namespace std;
7+
8+
constexpr int N = 5; // No. of vertices
9+
constexpr int L = 4; // ceil(logN / log2) + 1
10+
11+
// Vertices from 1 to N.
12+
vector<int> adj[N + 1];
13+
int up[N + 1][L];
14+
int level[N + 1];
15+
16+
void dfs(int u, int prev = 0)
17+
{
18+
up[u][0] = prev;
19+
for (auto &v : adj[u])
20+
{
21+
if (v == prev) continue;
22+
23+
level[v] = level[u] + 1;
24+
dfs(v, u);
25+
}
26+
}
27+
28+
void binaryLift()
29+
{
30+
dfs(1);
31+
for (int i = 1; i < L; i++)
32+
for (int j = 1; j <= N; j++)
33+
up[j][i] = up[up[j][i - 1]][i - 1];
34+
}
35+
36+
int LCA(int a, int b)
37+
{
38+
if (level[a] > level[b])
39+
swap(a, b);
40+
41+
int diff = level[b] - level[a];
42+
for (int i = 0; i < L; i++)
43+
{
44+
if ((diff & (1 << i)))
45+
b = up[b][i];
46+
}
47+
48+
if (a == b) return a;
49+
50+
for (int i = L - 1; i >= 0; i--)
51+
{
52+
if (up[a][i] != up[b][i])
53+
{
54+
a = up[a][i];
55+
b = up[b][i];
56+
}
57+
}
58+
return up[a][0];
59+
}
60+
61+
void addEdge(int u, int v)
62+
{
63+
adj[u].push_back(v);
64+
adj[v].push_back(u);
65+
}
66+
67+
int dist(int a, int b)
68+
{
69+
return level[a] + level[b] - 2 * level[LCA(a, b)];
70+
}
71+
72+
int main()
73+
{
74+
addEdge(1, 2);
75+
addEdge(1, 3);
76+
addEdge(2, 4);
77+
addEdge(2, 5);
78+
79+
binaryLift();
80+
81+
cout << "LCA:\n";
82+
cout << LCA(4, 3) << "\n";
83+
cout << LCA(4, 5) << "\n";
84+
cout << LCA(4, 2) << "\n";
85+
86+
cout << "Distances:\n";
87+
cout << dist(4, 3) << "\n";
88+
cout << dist(4, 5) << "\n";
89+
cout << dist(4, 2) << "\n";
90+
91+
return 0;
92+
}

0 commit comments

Comments
 (0)