diff --git a/Graph/lca.cpp b/Graph/lca.cpp index b0ff12750..70a9e3e42 100644 --- a/Graph/lca.cpp +++ b/Graph/lca.cpp @@ -1,90 +1,120 @@ #include + 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 adj[N]; // Graph - int up[LG][N]; // build this table - int level[N]; // get the levels of all of them +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>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> 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 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]; - } + 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. +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. }