#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int cnt,n,m,s,last[500005],f[500005][22],dep[500005],logg[500005];
struct edge{
int next,v,u;
}e[1000010];
inline void inserts(int u,int v)
{
cnt++;
e[cnt].next=last[u];
e[cnt].u=u;
e[cnt].v=v;
last[u]=cnt;
}
void read(int & x)
{
char c=getchar();x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')
x=x*10+c-48,c=getchar();
}
void dfs(int u,int v)
{
for (int i=1;i<=20;i++) f[v][i]=f[f[v][i-1]][i-1];
for(int i=last[v];i;i=e[i].next)
{
int x=e[i].v;
if(x!=u)
{
dep[x]=dep[v]+1;
f[x][0]=v;
dfs(v,x);
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
swap(x,y);
while(dep[x]!=dep[y])
x=f[x][logg[dep[x]-dep[y]]];
if(x==y)
return x;
for(int k=logg[dep[x]];k>=0;k--)
if(f[x][k]!=f[y][k])
x=f[x][k],y=f[y][k];
return f[x][0];
}
int main()
{
read(n);read(m);read(s);
for(int i=1,x,y;i<=n-1;i++)
{
read(x);read(y);
inserts(x,y);
inserts(y,x);
}
f[s][0]=0;
dep[s]=1;
dfs(0,s);
logg[1]=0;
for(int i=2;i<=n;i++)
logg[i]=logg[i-1]+((1<<logg[i-1]+1)==i);
// for (int i=2;i<=n;i++) logg[i]=log[i>>1]+1;
for(int i=1,x,y,z;i<=m;i++)
{
read(x);read(y);
z=lca(x,y);
printf("%d\n",z);
}
return 0;
}
树上倍增求LCA
最新推荐文章于 2023-02-11 10:08:55 发布