#include<bits/stdc++.h>
using namespace std;
const int LOGN=18;
const int N=100010*5;
struct node{
int to,nxt,w;
}e[2*N];
int tot,n,m,s,depth[N],f[N][22],head[N];
void add(int x,int y){
e[++tot].to=y;
e[tot].nxt=head[x];
head[x]=tot;
}
void dfs(int u,int fa){
depth[u]=depth[fa]+1;
f[u][0]=fa;
for(int i=1;(1<<i)<=depth[u];i++)
f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u];i>0;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs(v,u);
}
}
int lca(int x,int y){
if(depth[x]<depth[y])swap(x,y);//让x更深点
for(int i=LOGN;i>=0;--i)//将x跳到和y同一深度
if(depth[f[x][i]]>=depth[y])
x=f[x][i];
if(x==y)return x;
for(int i=LOGN;i>=0;--i)//一起向上跳
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];//两个点均在其最近公共祖先的下方,再往上跳一次
}
/*
int c=depth[a]-depth[b];
for(int i=0;i<=14;i++)
if(c&(l<<i))
a=up[a][i];
跳同层位运算优化
*/
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(s,0);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}
LCA代码
最新推荐文章于 2022-02-27 10:34:01 发布