RainX_69

LCA Queries using BINARY LIFTING

Dec 19th, 2022
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.12 KB | Source Code | 0 0
  1. /*
  2. Que_link- https://www.spoj.com/problems/LCA/
  3.  
  4. A tree is an undirected graph in which any two vertices are connected by exactly one simple path. In other words, any connected graph without cycles is a tree. - Wikipedia
  5.  
  6. The lowest common ancestor (LCA) is a concept in graph theory and computer science. Let T be a rooted tree with N nodes. The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself). - Wikipedia
  7.  
  8. Your task in this problem is to find the LCA of any two given nodes v and w in a given tree T.
  9.                                                  1
  10.                                               /  |  \
  11.                                              2   3   4
  12.                                               /  | \____
  13.                                              5   6      7
  14.                                                /  \    /  \
  15.                                               8    9  10   11
  16.                                                       / \
  17.                                                      12 13
  18. For example the LCA of nodes 9 and 12 in this tree is the node number 3.
  19.  
  20. Input
  21. The first line of input will be the number of test cases. Each test case will start with a number N the number of nodes in the tree, 1 <= N <= 1,000. Nodes are numbered from 1 to N. The next N lines each one will start with a number M the number of child nodes of the Nth node, 0 <= M <= 999 followed by M numbers the child nodes of the Nth node. The next line will be a number Q the number of queries you have to answer for the given tree T, 1 <= Q <= 1000. The next Q lines each one will have two number v and w in which you have to find the LCA of v and w in T, 1 <= v, w <= 1,000.
  22.  
  23. Input will guarantee that there is only one root and no cycles.
  24.  
  25. Output
  26. For each test case print Q + 1 lines, The first line will have “Case C:” without quotes where C is the case number starting with 1. The next Q lines should be the LCA of the given v and w respectively.
  27.  
  28. Example
  29. Input:
  30. 1
  31. 7
  32. 3 2 3 4
  33. 0
  34. 3 5 6 7
  35. 0
  36. 0
  37. 0
  38. 0
  39. 2
  40. 5 7
  41. 2 7
  42.  
  43. Output:
  44. Case 1:
  45. 3
  46. 1
  47. */
  48.  
  49. #include<bits/stdc++.h>
  50. using namespace std;
  51.  
  52. int dp[1001][11];
  53. int level[1001];
  54. list<int>* adj;
  55. int parent[1001];
  56.  
  57. void DFS(int node, int depth){
  58.     level[node]=depth;
  59.     for(auto nei: adj[node]){
  60.         DFS(nei,depth+1);
  61.     }
  62. }
  63.  
  64. void precomputation(int n){
  65.     for(int node=1;node<=n;node++){
  66.         dp[node][0]=parent[node];
  67.     }
  68.     for(int node=1;node<=n;node++){
  69.         for(int jump=1;jump<11;jump++){
  70.             if(dp[node][jump-1]!=-1){
  71.                 dp[node][jump]=dp[dp[node][jump-1]][jump-1];
  72.             }
  73.         }
  74.     }
  75. }
  76.  
  77. void moveUP(int &node, int k){
  78.     for(int jump=10;jump>=0;jump--){
  79.         if(k>=pow(2,jump)){
  80.             k-=pow(2,jump);
  81.             node=dp[node][jump];
  82.             if(node==-1){
  83.                 return;
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. int LCA(int node1, int node2){
  90.     if(level[node1]>level[node2]){
  91.         moveUP(node1,level[node1]-level[node2]);
  92.     }
  93.     if(level[node1]<level[node2]){
  94.         moveUP(node2,level[node2]-level[node1]);
  95.     }
  96.     if(node1==node2){
  97.         return node1;
  98.     }
  99.     for(int jump=10;jump>=0;jump--){
  100.         if(dp[node1][jump]!=-1 && dp[node1][jump]!=dp[node2][jump]){
  101.             node1=dp[node1][jump];
  102.             node2=dp[node2][jump];
  103.         }
  104.     }
  105.     return dp[node1][0];
  106. }
  107.  
  108.  
  109. void solve(){
  110.     int N;
  111.     cin>>N;
  112.     adj=new list<int>[N+1];
  113.     for(int node=1;node<=N;node++){
  114.         int m;
  115.         cin>>m;
  116.         int in;
  117.         while(m--){
  118.             cin>>in;
  119.             adj[node].push_back(in);
  120.             parent[in]=node;
  121.         }
  122.     }
  123.     DFS(1,1);
  124.     precomputation(N);
  125.     int q;
  126.     cin>>q;
  127.     while(q--){
  128.         int node1,node2;
  129.         cin>>node1>>node2;
  130.         cout<<LCA(node1,node2)<<endl;
  131.     }
  132. }
  133.  
  134. int main(){
  135.     int TC;
  136.     cin>>TC;
  137.     int num=1;
  138.     while(TC--){
  139.         memset(dp,-1,sizeof(dp));
  140.         memset(parent,-1,sizeof(parent));
  141.         memset(level,0,sizeof(level));
  142.         cout<<"Case "<<num++<<":"<<endl;
  143.         solve();
  144.     }
  145. }
  146.  
Advertisement
Add Comment
Please, Sign In to add comment