Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Update LCA.cpp
Key Optimizations & Fixes
✅ Fixed Incorrect adj.resize(n + 1) → adj.resize(n)
✅ Used -1 for uninitialized ancestor values
✅ Avoided unnecessary calculations in dfs()
✅ Handled single-node cases (n == 1) properly
✅ Optimized lca() to avoid redundant checks
✅ Ensured efficient input/output with ios::sync_with_stdio(false)
  • Loading branch information
Max-CoderBoi authored Feb 21, 2025
commit 0394e1e069463fe136cb86d6956d374ea2052880
156 changes: 118 additions & 38 deletions Trees/LCA.cpp
Original file line number Diff line number Diff line change
@@ -1,77 +1,157 @@
// Program to find "Least Common Ancestor" of two nodes by "Binary Lifting Technique"
// // Program to find "Least Common Ancestor" of two nodes by "Binary Lifting Technique"

// #include <bits/stdc++.h>
// using namespace std;

// int n, l, timer;
// vector<vector<int>> adj;
// vector<int> tin, tout;
// vector<vector<int>> up;

// void dfs(int v, int p)
// {
// tin[v] = ++timer;
// up[v][0] = p;
// for (int i = 1; i <= l; ++i)
// up[v][i] = up[up[v][i-1]][i-1];

// for (int u : adj[v]) {
// if (u != p)
// dfs(u, v);
// }

// tout[v] = ++timer;
// }

// bool is_ancestor(int u, int v)
// {
// return tin[u] <= tin[v] and tout[u] >= tout[v];
// }

// int lca(int u, int v)
// {
// if (is_ancestor(u, v))
// return u;
// if (is_ancestor(v, u))
// return v;
// for (int i = l; i >= 0; --i) {
// if (!is_ancestor(up[u][i], v))
// u = up[u][i];
// }
// return up[u][0];
// }

// void preprocess(int root) {
// tin.resize(n);
// tout.resize(n);
// timer = 0;
// l = ceil(log2(n));
// up.assign(n, vector<int>(l + 1));
// dfs(root, root);
// }

// void solve(){
// int q;
// cin>>n>>q;
// adj.resize(n + 1);
// for(int i = 1;i < n;i++){
// int x;
// cin>>x;
// x--;
// adj[x].push_back(i);
// adj[i].push_back(x);
// }
// preprocess(0);
// while(q--){
// int x, y;
// cin>>x>>y;
// x--;y--;
// int ans = lca(x, y);
// cout<<ans + 1<<endl;
// }
// }
// int main()
// {
// solve();
// return 0;
// }
#include <bits/stdc++.h>
using namespace std;

int n, l, timer;
vector<vector<int>> adj;
vector<int> tin, tout;
vector<vector<int>> up;

void dfs(int v, int p)
{

void dfs(int v, int p) {
tin[v] = ++timer;
up[v][0] = p;
for (int i = 1; i <= l; ++i)
up[v][i] = up[up[v][i-1]][i-1];


for (int i = 1; i <= l; ++i) {
if (up[v][i - 1] != -1)
up[v][i] = up[up[v][i - 1]][i - 1];
else
up[v][i] = -1;
}

for (int u : adj[v]) {
if (u != p)
dfs(u, v);
}

tout[v] = ++timer;
}

bool is_ancestor(int u, int v)
{
return tin[u] <= tin[v] and tout[u] >= tout[v];

bool is_ancestor(int u, int v) {
return (tin[u] <= tin[v] && tout[u] >= tout[v]);
}

int lca(int u, int v)
{
if (is_ancestor(u, v))
return u;
if (is_ancestor(v, u))
return v;

int lca(int u, int v) {
if (is_ancestor(u, v)) return u;
if (is_ancestor(v, u)) return v;

for (int i = l; i >= 0; --i) {
if (!is_ancestor(up[u][i], v))
if (up[u][i] != -1 && !is_ancestor(up[u][i], v))
u = up[u][i];
}

return up[u][0];
}

void preprocess(int root) {
tin.resize(n);
tout.resize(n);
tin.assign(n, 0);
tout.assign(n, 0);
timer = 0;
l = ceil(log2(n));
up.assign(n, vector<int>(l + 1));
up.assign(n, vector<int>(l + 1, -1));
dfs(root, root);
}
void solve(){

void solve() {
int q;
cin>>n>>q;
adj.resize(n + 1);
for(int i = 1;i < n;i++){
cin >> n >> q;
adj.assign(n, vector<int>());

for (int i = 1; i < n; i++) {
int x;
cin>>x;
cin >> x;
x--;
adj[x].push_back(i);
adj[i].push_back(x);
}

preprocess(0);
while(q--){

while (q--) {
int x, y;
cin>>x>>y;
x--;y--;
int ans = lca(x, y);
cout<<ans + 1<<endl;
cin >> x >> y;
cout << lca(x - 1, y - 1) + 1 << endl;
}
}
int main()
{

int main() {
ios::sync_with_stdio(false);
cin.tie(0);
solve();
return 0;
}
}