倍增
#include<bits/stdc++.h>
//#define max(a,b) (((a) > (b)) ? (a) : (b))
using namespace std;
int n,T,root,deep[500010],maxdeep,f[500010][25];
int tot,h[500010],top;
struct node{
int next,to;
}e[2*500010];
void add(int u,int v)
{
++tot;
e[tot].to=v;
e[tot].next=h[u];
h[u]=tot;
}
void build(int u)
{
for(int i=h[u]; i; i=e[i].next)
{
int v=e[i].to;
if(v != f[u][0])
{
deep[v]=deep[u]+1;
f[v][0]=u;
maxdeep=max(maxdeep,deep[v]);
build(v);
}
}
}
int lca(int u,int v)
{
if(deep[u] < deep[v]) swap(u,v);
for(int i=top; i>=0; i--) if(deep[f[u][i]] >= deep[v]) u=f[u][i];
if(u == v) return v;
for(int i=top; i>=0; i--)
{
if(f[u][i] != f[v][i])
{
u=f[u][i];
v=f[v][i];
}
}
return f[u][0]; // 注意!!
}
int main()
{
scanf("%d%d%d",&n,&T,&root);
for(int i=1; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
deep[root]=1;
build(root);
for( ; (1<<top) <= maxdeep; top++);
for(int j=1; j<=top; j++)
for(int i=1; i<=n; i++)
f[i][j]=f[f[i][j-1]][j-1];
while (T--)
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
}
return 0;
}
tarjan
留坑