题目链接 https://www.luogu.org/problemnew/show/3379
#include <cstdio>
#include <algorithm>
#define Add(x,y) (to[++num]=head[x],head[x]=num,V[num]=y)
#define For(x) for(int h=head[x],o=V[h]; h; o=V[h=to[h]])
using namespace std;
int head[500005],to[1000005],V[1000005],num;
int ST[500005][25],d[500005];
int n,m,s,a,b;
void dfs(int x,int Fa,int dep){
d[x]=dep;
For(x) if (o!=Fa){
ST[o][0]=x;
dfs(o,x,dep+1);
}
}
void getST(){
for (int j=1; j<=20; j++)
for (int i=1; i<=n; i++)
ST[i][j]=ST[ST[i][j-1]][j-1];
}
int FA(int x,int y){ //x 的第 y 代祖先
for (int i=0; y; i++,y>>=1)
if (y&1) x=ST[x][i];
return x;
}
int LCA(int x,int y){
if (d[x]<d[y]) swap(x,y);
x=FA(x,d[x]-d[y]); //使得 x 和 y 处于同一深度
if (x==y) return x; //一样就直接返回值
for (int i=20; i>=0; i--)
if (ST[x][i]!=ST[y][i])
x=ST[x][i],y=ST[y][i]; //一直将 x,y 往上挪找到最上面那层不一样的
return ST[x][0]; //再往上一层就是答案
}
int main(){
freopen("1.txt","r",stdin);
scanf("%d%d%d",&n,&m,&s);
for (int i=1; i<n; i++)
scanf("%d%d",&a,&b),Add(a,b),Add(b,a);
dfs(s,0,0);
getST();
while (m--){
scanf("%d%d",&a,&b);
printf("%d\n",LCA(a,b));
}
}