mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-08 13:06:57 +08:00
Added LCA binary Lifting O(nlogn)
This commit is contained in:
90
Graph/lca.cpp
Normal file
90
Graph/lca.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
// Find the lowest common ancestor using binary lifting in O(nlogn)
|
||||
// Zero based indexing
|
||||
// Resource : https://cp-algorithms.com/graph/lca_binary_lifting.html
|
||||
const int N = 1005;
|
||||
const int LG = log2(N)+1;
|
||||
struct lca{
|
||||
int n;
|
||||
vector<int> adj[N]; // Graph
|
||||
int up[LG][N]; // build this table
|
||||
int level[N]; // get the levels of all of them
|
||||
|
||||
lca(int n_) : n(n_){
|
||||
memset(up,-1,sizeof(up));
|
||||
memset(level,0,sizeof(level));
|
||||
for(int i=0; i<n-1; ++i){
|
||||
int a,b;
|
||||
cin>>a>>b; a--; b--;
|
||||
adj[a].push_back(b);
|
||||
adj[b].push_back(a);
|
||||
}
|
||||
level[0] = 0;
|
||||
dfs(0,-1);
|
||||
build();
|
||||
}
|
||||
void verify(){
|
||||
for(int i=0; i<n; ++i){
|
||||
cout<<i<<" : level: "<<level[i]<<endl;
|
||||
}
|
||||
cout<<endl;
|
||||
for(int i=0; i<LG; ++i){
|
||||
cout<<"Power:"<<i<<": ";
|
||||
for(int j=0; j<n; ++j){
|
||||
cout<<up[i][j]<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
void build(){
|
||||
for(int i=1; i<LG; ++i){
|
||||
for(int j=0; j<n; ++j){
|
||||
if( up[i-1][j] != -1 ){
|
||||
up[i][j] = up[i-1][up[i-1][j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs(int node, int par){
|
||||
up[0][node] = par;
|
||||
for( auto i : adj[node] ){
|
||||
if( i != par ){
|
||||
level[i] = level[node] + 1;
|
||||
dfs(i,node);
|
||||
}
|
||||
}
|
||||
}
|
||||
int query(int u, int v){
|
||||
u--; v--;
|
||||
if( level[v] > level[u] ){ swap(u,v); }
|
||||
// u is at the bottom.
|
||||
int dist = level[u] - level[v];
|
||||
// Go up this much distance
|
||||
for(int i=LG-1; i>=0; --i){
|
||||
if( dist & ( 1 << i) ){
|
||||
u = up[i][u];
|
||||
}
|
||||
}
|
||||
if( u == v ){ return u; }
|
||||
assert(level[u] == level[v]);
|
||||
for(int i=LG-1; i>=0; --i){
|
||||
if( up[i][u] != up[i][v] ){
|
||||
u = up[i][u];
|
||||
v = up[i][v];
|
||||
}
|
||||
}
|
||||
assert(up[0][u] == up[0][v]);
|
||||
return up[0][u];
|
||||
}
|
||||
};
|
||||
|
||||
int main(){
|
||||
int n; // number of nodes in the tree.
|
||||
lca l(n); // will take the input in the format given
|
||||
// n-1 edges of the form
|
||||
// a b
|
||||
// Use verify function to see.
|
||||
}
|
||||
Reference in New Issue
Block a user