Skip to content

Commit c9fae93

Browse files
author
Mohamed Ayman
committed
Add Lowest commen ancestor algorithm
1 parent 68ad0f2 commit c9fae93

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/lca_demo.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <bits/stdc++.h>
2+
3+
int numberOfNodes, MAXLOG;
4+
std::vector< std::vector<int> > adjList;
5+
int parent[50005], nodeHeight[50005];
6+
bool visited[50005];
7+
int binaryLiftDp[50005][27];
8+
9+
void dfs(int currentNode, int currentParent)
10+
{
11+
visited[currentNode] = true;
12+
parent[currentNode] = currentParent;
13+
nodeHeight[currentNode] = nodeHeight[currentParent] + 1;
14+
int adjacencySize = adjList[currentNode].size();
15+
for(int idx = 0; idx < adjacencySize; idx++){
16+
int nextNode = adjList[currentNode][idx];
17+
if(!visited[nextNode])
18+
{
19+
dfs(nextNode, currentNode);
20+
}
21+
}
22+
}
23+
24+
int getMaxLog(){
25+
int curValue = 1;
26+
int curLog = 1;
27+
while(curValue < numberOfNodes) curValue *= 2, curLog++;
28+
return curLog;
29+
}
30+
31+
void initializeDP()
32+
{
33+
nodeHeight[-1] = -1;
34+
MAXLOG = getMaxLog();
35+
dfs(0, -1);
36+
for(int i = 0; i < numberOfNodes; i++) binaryLiftDp[i][0] = parent[i];
37+
for(int i = 1; i <= MAXLOG; i++)
38+
{
39+
for(int j = 0; j < numberOfNodes; j++)
40+
{
41+
if(binaryLiftDp[j][i - 1] + 1)
42+
binaryLiftDp[j][i] = binaryLiftDp[binaryLiftDp[j][i - 1]][i - 1];
43+
else binaryLiftDp[j][i] = -1;
44+
}
45+
}
46+
}
47+
48+
int LCA(int a, int b)
49+
{
50+
if(nodeHeight[a] < nodeHeight[b]) std::swap(a,b);
51+
for(int i = MAXLOG; i >= 0; i--)
52+
{
53+
if(binaryLiftDp[a][i] + 1 && nodeHeight[binaryLiftDp[a][i]] >= nodeHeight[b])
54+
a = binaryLiftDp[a][i];
55+
}
56+
if(!(a - b)) return a;
57+
for(int i = MAXLOG; i >= 0; i--)
58+
{
59+
if(binaryLiftDp[a][i] + 1 && binaryLiftDp[a][i] - binaryLiftDp[b][i])
60+
a = binaryLiftDp[a][i], b = binaryLiftDp[b][i];
61+
}
62+
return parent[a];
63+
}
64+
65+
void buildTree()
66+
{
67+
printf("Enter number of nodes of the tree: ");
68+
scanf("%d", &numberOfNodes);
69+
adjList.resize(numberOfNodes, std::vector<int> ());
70+
for(int i = 0; i < numberOfNodes - 1; i++)
71+
{
72+
int firstNode, secondNode;
73+
printf("Enter the two nodes to be connected: ");
74+
scanf("%d %d", &firstNode, &secondNode);
75+
adjList[firstNode].push_back(secondNode);
76+
adjList[secondNode].push_back(firstNode);
77+
}
78+
}
79+
80+
void answerQueries()
81+
{
82+
int queryCount;
83+
printf("Enter the number of queries: ");
84+
scanf("%d", &queryCount);
85+
for(int i = 0; i < queryCount; i++)
86+
{
87+
int firstNode, secondNode;
88+
printf("Enter the two nodes : ");
89+
scanf("%d %d", &firstNode, &secondNode);
90+
printf("%d\n", LCA(firstNode, secondNode));
91+
}
92+
}
93+
94+
int main()
95+
{
96+
buildTree();
97+
initializeDP();
98+
answerQueries();
99+
}

0 commit comments

Comments
 (0)