Skip to content

Commit 531701f

Browse files
authored
Create LCA_binary_lifting.cpp
adding a sample problem of finding distance between two nodes in a tree for eg, if nodes are A and B then dist(A,B) = depth(A) + depth(B) - 2*LCA(A,B) here calculating LCA in efficient time is crucial. so there is a technique called binary lifting which calculates LCA in log(n) time
1 parent 4510fd0 commit 531701f

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
2+
/* find least common ancestor
3+
4+
time complexity O(logn)
5+
6+
using binary lifting
7+
8+
*/
9+
10+
11+
#include<iostream>
12+
using namespace std;
13+
#include<queue>
14+
#include<map>
15+
#include<math.h>
16+
#define lli long long int
17+
#include<vector>
18+
#define vi vector<int>
19+
#define fo(i,n) for(int i=1;i<=n;i++)
20+
#define maxN 10
21+
#include <bits/stdc++.h>
22+
23+
//ques--- find the dist bw two nodes in a tree
24+
25+
26+
vi adj[1001];
27+
vi level(1001);
28+
29+
int LCA[1001][maxN+1];
30+
31+
void dfs(int node, int lvl, int parent){
32+
33+
level[node]=lvl;
34+
LCA[node][0]=parent;
35+
//cout<<node<<"jiji";
36+
37+
for(int child: adj[node]){
38+
if(child!=parent)
39+
dfs(child,lvl+1,node);
40+
}
41+
42+
}
43+
44+
void init(int n){
45+
dfs(1,0,-1);
46+
47+
for(int j=1;j<=maxN;j++){
48+
for(int i=1;i<=n;i++){
49+
if(LCA[i][j-1]!=-1){
50+
int temp=LCA[i][j-1];
51+
LCA[i][j] = LCA[temp][j-1];
52+
}
53+
else LCA[i][j] = -1;
54+
}
55+
}
56+
}
57+
58+
59+
60+
61+
// this returns the least common ancestor of two nodes a and b
62+
63+
64+
int getLCA(int a, int b){
65+
66+
int diff;
67+
68+
if(level[b]<level[a]) swap(a,b);
69+
70+
diff = level[b] - level[a];
71+
72+
while(diff>0){
73+
int i = log2(diff);
74+
75+
b = LCA[b][i];
76+
77+
diff -= (1<<i);
78+
}
79+
80+
if(a == b) return a;
81+
82+
for(int i=maxN;i>=0;i--){
83+
if(LCA[a][i]!=-1 && (LCA[a][i]!=LCA[b][i]))
84+
a = LCA[a][i], b = LCA[b][i];
85+
}
86+
87+
return LCA[a][0];
88+
}
89+
90+
int getDist(int a, int b){
91+
92+
int lca=getLCA(a,b);
93+
//if(level[a]>level[b])
94+
return level[a] + level[b] - 2*level[lca];
95+
96+
}
97+
98+
int main(){
99+
// now working fine :)))
100+
101+
// it was throwing running time error from 2 hours
102+
// bcoz in for loop there was i = 0; i<=maxN i.e, maxN+1 times
103+
// while I declared LCA as LCA[1001][maxN] should be maxN+1 or bigg....
104+
// so remember while assigning sizes globally.
105+
int n,a,b; cin>>n;
106+
107+
fo(i,n-1)
108+
cin>>a>>b, adj[a].push_back(b), adj[b].push_back(a);
109+
110+
init(n);
111+
112+
113+
114+
int q; cin>>q;
115+
116+
while(q--){
117+
cin>>a>>b;
118+
int d= getDist(a,b);
119+
cout<<d<<endl;
120+
}
121+
122+
}

0 commit comments

Comments
 (0)