社区讨论
倍增求LCA 70pts求条
P3379【模板】最近公共祖先(LCA)参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mhjaxf6m
- 此快照首次捕获于
- 2025/11/03 23:35 4 个月前
- 此快照最后确认于
- 2025/11/03 23:35 4 个月前
记录:https://www.luogu.com.cn/record/234152299
CPP#include<bits/stdc++.h>
using namespace std;
const int MaxN=5e5;
int head[MaxN+5],Next[2*MaxN+5],to[2*MaxN+5],dep[MaxN+5];
int fno[MaxN][25];
int cnt;
void add(int x,int y)
{
Next[++cnt]=head[x];
to[cnt]=y;
head[x]=cnt;
}
int dfs(int n,int f)//n为当前节点编号 f为父亲编号
{
fno[n][0]=f;//认父亲
dep[n]=dep[f]+1;
for(int i=1;i<=21;++i)fno[n][i]=fno[fno[n][i-1]][i-1];//倍增
for(int i=head[n];i;i=Next[i])//递归子节点
{
if(to[i]!=f)//排除父亲
{
dfs(to[i],n);
}
}
return 0;
}
int lca(int x,int y)
{
if(x==y)return x;
if(dep[x]<dep[y])swap(x,y);//使得x更深
for(int trip=21;trip>=0;trip--)//调整到同一深度
{
if(dep[fno[x][trip]]>=dep[y])x=fno[x][trip];
}
if(x==y)return x;
for(int trip=21;trip>=0;trip--)//倍增
{
if(fno[x][trip]==fno[y][trip])continue;
x=fno[x][trip],y=fno[y][trip];
}
return fno[x][0];
}
int main()
{
int n,m,root;
scanf("%d %d %d",&n,&m,&root);
--n;
while(n--)
{
int a,b;
scanf("%d %d",&a,&b);
add(a,b); add(b,a);
}
dfs(root,0);
fno[root][0]=0;
while(m--)
{
int x,y;
scanf("%d %d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...