1. 程式人生 > 其它 >樹上倍增求LCA

樹上倍增求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];
}