LCA的倍增算法,算是一种比较好些并且使用率很高的算法了
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
const int N=500005;
struct node{
int x,y,nxt;
};
node way[N<<1];
int pre[N][20],deep[N],n,m,root,st[N],tot=0,lg;
void add(int u,int w)
{
tot++;
way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
tot++;
way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;
}
void dfs(int now,int fa,int dep)
{
deep[now]=dep;
pre[now][0]=fa;
for (int i=st[now];i;i=way[i].nxt)
if (way[i].y!=fa)
dfs(way[i].y,now,dep+1);
}
void cl()
{
lg=log(n)/log(2)+1;
for (int i=1;i<=lg;i++)
for (int j=1;j<=n;j++)
pre[j][i]=pre[pre[j][i-1]][i-1];
}
int ask(int u,int w)
{
if (deep[u]<deep[w]) swap(u,w);
int d=deep[u]-deep[w];
if (d)
for (int i=0;i<=lg&&d;i++,d>>=1)
if (d&1)
u=pre[u][i];
if (u==w) return u;
for (int i=lg;i>=0;i--)
if (pre[u][i]!=pre[w][i])
{
u=pre[u][i];
w=pre[w][i];
}
return pre[u][0];
}
int main()
{
scanf("%d%d%d",&n,&m,&root);
for (int i=1;i<n;i++)
{
int u,w;
scanf("%d%d",&u,&w);
add(u,w);
}
dfs(root,0,1);
cl();
for (int i=1;i<=m;i++)
{
int u,w;
scanf("%d%d",&u,&w);
printf("%d\n",ask(u,w));
}
return 0;
}