Wednesday, 2 March 2016

LCA CODE (MY code both binary rais and segtree )

//  node of the tree is 1 based index so if in any problem nodes are
// 0 based than make it 1 based by increasein 1 each node while
// makin graph , also at  the time of query increase by 1
// all array euler[1000000],level[1000000],f_occ[1000000]  are 0 based index
//  seg tree is 1 based index .....

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
int euler[1000000],level[1000000],f_occ[1000000];
int id=0;
list<int > li[1000000];
int kk=0;
lli dist[1000000];
#define inf 100000000
struct st
 {
  int val;
  int index;
 }  tree[1000000];



 void dfs(int start,int lev,int par)
  {
    euler[id]=start;
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
 
   list<int>:: iterator it;
   for(it=li[start].begin();it!=li[start].end();it++)
    {
      if(*it!=par)
       {
    dfs(*it,lev+1,start);
    euler[id]=start;
    level[id]=lev;
    f_occ[start]=min(f_occ[start],id);
    id++;
    }
    }
 
  }

st query(int node,int start,int end,int r1,int r2)
 {
 if(start>end || r1>end || r2<start)
 {
     st ab;
  ab.val=inf;
  ab.index=-1;
  return ab;
 }
   if(r1<=start && r2>=end)
    {
     return tree[node];
    }
    else
    {
     st q1=query(2*node,start,(start+end)/2,r1,r2);
     st q2=query(2*node+1,((start+end)/2)+1,end,r1,r2);
     if(q1.val<q2.val) return q1;
     else return q2;
    }
 }

void build(int node , int start,int end)
 {

  if(start==end)
  {
   tree[node].val=level[start];
   tree[node].index=start;
   return ;
  }
  else if(start>end)
  {
    tree[node].val=inf;
    tree[node].index=-1;
    return ;
   }
  else
   {
    build(2*node,start,(start+end)/2);
    build(2*node+1,((start+end)/2)+1,end);
    if(tree[2*node].val<tree[2*node+1].val)
    {
     tree[node].val=tree[2*node].val;
     tree[node].index=tree[2*node].index;
 }
 else
 {
   tree[node].val=tree[2*node+1].val;
     tree[node].index=tree[2*node+1].index;
 }
 
   }
 }

  int main()
   {
     int n;
      cin>>n;
      for(int i=0;i<n-1;i++)
       {
         int a,b,c;
          cin>>a>>b;
          li[a].push_back(b);
          li[b].push_back(a);
    }
 
   for(int i=0;i<=2*n;i++) f_occ[i]=1000000;
    dfs(1,1,0);
    id--;
    build(1,0,id);
    int q;
    cin>>q;
    while(q--)
     {
        int a,b;
         cin>>a>>b;
          int x1=f_occ[a];
          int x2=f_occ[b];
          if(x1>x2) swap(x1,x2);
     st lc=query(1,0,id,x1,x2);
     int lca=euler[lc.index];
     cout<<lca<<endl;    
    }
   }


---------------------------------------------------------binary rais----------------------------------------
// tree is treated as 1 based
// level is also 1 based

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
list<int>li[1010];
lli dp[1010][30];
int lev[1010];
int dfs(int start,int par,int le)
{

  lev[start]=le;
  list<int>:: iterator it;
  for(it=li[start].begin();it!=li[start].end();it++)
   {
     if(*it!=par)
      {
        dp[*it][0]=start;
        lev[*it]=le+1;
        dfs(*it,start,le+1);
   }
   }
}


int binary_rais(int a,int b)// return lca of a,b
 {
 
   
   if(lev[a]<lev[b]) swap(a,b);
 
   int lg;
 
   /// maximum jump that can be alloweable to make both a and
   // b at same level  will be the depth of the node a
   for(lg=1;(1<<lg)<=lev[a];lg++);
 
   //
   lg--;
 
   // this will make both at same level
   //  we can write any number as the power of 2
   //  so by binary raise we can reach to any node
     for(int i=lg;i>=0;i--)
      {
        if(lev[a]-(1<<i)>=lev[b])
         {
            a=dp[a][i];//   moving a upward
          }
      }
   
    //  now a and b are at same level
     // cout<<" at same level "<<a<<" "<<b<<endl;
   if(a==b) return a;
 
   else
   {
    for(int i=lg;i>=0;i--)
    {
     if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])//  moving botha and b up
      {
        a=dp[a][i];
        b=dp[b][i];
      }
    }
    return dp[a][0];
   }
 }


int main()
{

 int t;
  cin>>t;
  int cas=1;
  while(t--)
  {
    cout<<"Case "<<cas++<<":"<<endl;
    for(int i=0;i<1010;i++)li[i].clear();
 int n;
 cin>>n;
 int m ;
  cin>>m;// edge
 
 for(int i=1;i<=m;i++)
 {
  int a,b;
   cin>>a>>b;
   li[a].push_back(b);
   li[b].push_back(a);
}

 memset(dp,-1,sizeof dp);
 // we are consedering 1 as the root of all nodes
 // so its parent is non so its pow(2,0) the parent is 0;

 dp[1][0]=0;
 dfs(1,-1,1);

    int max_h=20;//  or lon(n)
    //  maximum height
    for(int i=1;i<=max_h;i++)
     {
       for(int j=1;j<=n;j++)
        {
            if(dp[j][i-1]!=-1)
       dp[j][i]=dp[dp[j][i-1]][i-1];//
     }
  }
 
  int q;
  cin>>q;
  while(q--)
   {
     int a,b;
      cin>>a>>b;
      cout<< binary_rais(a,b)<<endl;
   }
 }

}

No comments:

Post a Comment