Skip to content

Commit 631751d

Browse files
committed
Added LCA using Binary Lifting.
1 parent 810804c commit 631751d

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

Graph/binarylifting.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//author : Avishkar A. Hande
2+
#include<bits/stdc++.h>
3+
#define ll long long
4+
using namespace std;
5+
6+
const int maxS = 1e5+10;
7+
vector<ll> adj[maxS];
8+
9+
ll LOG;
10+
int timer;
11+
vector<int> tin, tout;
12+
vector<vector<int>> up;
13+
14+
/*
15+
Binary Lifting is mostly used to find Lowest Common Ancestor
16+
as it reduces the time complexity to log(n);
17+
*/
18+
19+
void dfs(int v, int p)
20+
{
21+
tin[v] = ++timer;
22+
up[v][0] = p;
23+
for (int i = 1; i <= LOG; ++i)
24+
up[v][i] = up[up[v][i-1]][i-1];
25+
26+
for (int u : adj[v]) {
27+
if (u != p)
28+
dfs(u, v);
29+
}
30+
31+
tout[v] = ++timer;
32+
}
33+
34+
bool is_ancestor(int u, int v)
35+
{
36+
return tin[u] <= tin[v] && tout[u] >= tout[v];
37+
}
38+
39+
int lca(int u, int v)
40+
{
41+
if (is_ancestor(u, v))
42+
return u;
43+
if (is_ancestor(v, u))
44+
return v;
45+
for (int i = LOG; i >= 0; --i) {
46+
if (!is_ancestor(up[u][i], v))
47+
u = up[u][i];
48+
}
49+
return up[u][0];
50+
}
51+
52+
void preprocess(int root, int n) {
53+
tin.resize(n);
54+
tout.resize(n);
55+
timer = 0;
56+
LOG = ceil(log2(n)) + 1;
57+
up.assign(n+1, vector<int>(LOG + 1));
58+
dfs(root, root);
59+
}
60+
61+
int main()
62+
{
63+
ll node, queries;
64+
cin >> node >> queries;
65+
for(int i = 0; i < node-1; i++){
66+
ll u, v;
67+
cin >> u >> v;
68+
adj[u].push_back(v);
69+
adj[v].push_back(u);
70+
}
71+
preprocess(1, node);
72+
while(queries--){
73+
ll a, b;
74+
cin >> a >> b;
75+
cout << lca(a, b) << endl;
76+
}
77+
}

0 commit comments

Comments
 (0)