倍增法求解LCA
倍增法求解LCA
不限于二叉树
pow(2,k-1)+pow(2,k-1)=pow(2,k)
倍增法的关键数组f[a][i]表示节点a的第2i个祖先,f[a][0]就是a的父亲
先DFS一遍,预处理f数组,再求解lca
求解lca的函数是先让更深的点上跳到另一点的深度,再让两者一起往上跳,直到两者lca的儿子,最后直接返回其中一点的父亲即可
代码示例
//链式前向星存图
#define N 100005
struct Edge{
int next,to;
}e[2*N];
int cnt;
int head[N];
int f[N][21],depth[N];
void Add_edge(int from,int to){
e[++cnt].to=to;
e[cnt].next=head[from];
head[from]=cnt;
}
void dfs(int u,int father){
f[u][0]=father;
depth[u]=depth[father]+1;
for(int i=1;depth[u]>=(1<<i);i++){
f[u][i]=f[f[u][i-1]][i-1];
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==father) continue;
dfs(v,u);
}
}
int lca(int x,int y){
if(depth[x]<depth[y]) swap(x,y);//让x深度更深
//用位掩码的方法把x抬到和y同深
int diff=depth[x]-depth[y];
for(int i=0;i<=20;i++){
if(diff&(1<<i)) x=f[x][i];
}
if(x==y) return x;
for(int i=20;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}

浙公网安备 33010602011771号