树上倍增求LCA

树上倍增求LCA
先跑一遍dfs,知道每个结点的父结点是谁,记录在root[x][0],“x”是当前结点,“root[x][0]”是x结点向上一步得到的点(也称为父结点)。
我们可以维护出来每个结点向上2k步会走到哪个结点。如果已经超出树的范围令root[x][k]=0
预处理一下LOG()
inline void Pre()
{
        for(int i=0,j=0,nex=2;i<=maxN;i++)
       {        if(i==nex) {nex<<=1;j++}
                 LOG[i]=j;
       }
}
深搜索一下
void dfs(int u,int fa)
{
       root[u][0]=fa;
      deep[u]=deep[fa]+1;
      for (int i=0;(1<<(i+1))<N;i++)
            root[u][i+1]=root[root[u][i]][i];
       for (int i=head[u],v;~i;i=edge[i].nex)
       {
              v=edge[i].to;
              if(v==fa) continue;
              dfs(v,u);
       }
}
求LCA
inline int _Lca(int x,int y)
{
        if (deep[x]<deep[y]) swap(x,y);
        int det=deep[x]-deep[y];
        for(int i=LOG[det];i>=0;i--)
             if((det>>i)&1) x=root[x][i];
        if(x==y) return x;
        for(int i=LOG[N];i>=0;i--)
        {
              if (root[x][i]^root[y][i])
              { x=root[x][i],y=root[y][i];}
        }
       return root[x][0];
}

posted @ 2022-03-04 14:49  心悟&&星际  阅读(24)  评论(0编辑  收藏  举报