Error404 Blog


Main Page


LCA Using Binary Lifting





Do BFS first for depth info wrt a random node.
                    
    void bfs(vector& adj,vector& par,VII& depth,int& n)
    {
        //arbitrarily root the tree
        VII vis(n,false);
        depth[0]=0;
        vis[0]=true;
        queue q;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(auto it:adj[u])
            if(!vis[it])
            {
                vis[it]=true;
                depth[it]=depth[u]+1;
                par[0][it]=u;
                q.push(it);
            }

        }
    }
                    
                

Preprocess Step
                    
    void preprocess(vector<VII>& par,int& n,int& D)
    {
        for(int d=0;d<=D;++d)
        {
            for(int i=0;i<n;++i)
            {
                
                int mid=par[d-1][i];
                if(mid!=-1)
                par[d][i]=par[d-1][mid];
            }
        }
    }
                    
                

Walk and LCA
                    
int walk(int i,int k,int& D,vector<VII>& par)
{
    //To make a node i at depth d
    for(int d=0;d<=D && i!=-1;++d)
    if((i<<d)&k)i=par[d][i];

    return i;
}
int LCA(int a,int b,vector<VII>& par,VII& depth,int &D)
{
    if(depth[a]>depth[b])
    a=walk(a,depth[a]-depth[b],D,par);
    else if(depth[b]>depth[a])
    b=walk(b,depth[b]-depth[a],D,par);

    if(a==b)
    return a;

    for(int d=D;d>=0;--d)
    {
        //to go close faster make big jumps
        if(par[d][a]!=par[d][b])
        {
            a=par[d][a];
            b=par[d][b];
        }
    }
    return par[0][a];
}


int D=log2(n);