forked from Raju1822/HacktoberFest_2021
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LCA_graph.cpp
103 lines (90 loc) · 2.5 KB
/
LCA_graph.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
const int maxN = 300005;
const int logN = 20;
int parent[maxN][logN]; // parent[i][j] is 2^j th parent of node i // for binary lifting ( parent which is at distance 2^j from that node)
int depth[maxN];
vector<int> adj[maxN];
int lca(int u, int v)
{
if (depth[u] < depth[v])
swap(u, v);
// binary lifting ki prakriya :)
for (int i = logN - 1; i >= 0; i--)
{
if (depth[parent[u][i]] >= depth[v])
u = parent[u][i];
}
if (u == v)
return u;
for (int i = logN - 1; i >= 0; i--)
{
if (parent[u][i] != parent[v][i])
{
u = parent[u][i];
v = parent[v][i];
}
}
return parent[u][0];
}
// shortest distance between 2 nodes in tree
int dist(int u, int v)
{
int x = lca(u, v);
return (depth[u] + depth[v] - 2 * depth[x]);
}
void dfs(int node)
{
// making the whole parent array for this node using dynamic programming
for (int j = 1; j < logN; j++)
{
// 2^j = 2*2^(j-1) same as 2^j = 2^(j-1)+2^(j-1) distance wala node
// that means first find 2^(j-1)th parent of current node {intermediate (lets say) ,
// find 2^(j-1)th parent of intermediate node
int intermediate = parent[node][j - 1];
parent[node][j] = parent[intermediate][j - 1];
}
for (auto child : adj[node])
{
if (!depth[child])
{
depth[child] = depth[node] + 1;
parent[child][0] = node; // first parent OR( 2^0 th parent we can say )
dfs(child);
}
}
}
int main()
{
int n, u, v, q, r;
//cout << "enter the number of nodes in tree \n";
cin >> n;
//cout << "enter the edges \n";
for (int i = 1; i < n; i++) // looping for n-1 eges
{
cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
depth[1] = 1;
dfs(1);
//cout<<"enter the number of query \n";
pair<int, int> p[3];
cin >> q;
while (q--)
{
cin >> r >> u >> v;
p[0].second = lca(r, u);
p[1].second = lca(r, v);
p[2].second = lca(u, v);
for (int i = 0; i < 3; i++)
{
int x = p[i].second;
p[i].first = dist(x, v) + dist(x, u) + dist(x, r);
}
sort(p, p + 3);
cout << p[0].second << endl;
//cout<<"LCA of "<<u<<" and "<<v<<"is "<<lca(u,v)<<endl;
}
}