#include<cstdio>
#include<iostream>
using namespace std;
int read()
{
int ret=0; char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
ret=(ret<<1)+(ret<<3)+ch-'0',ch=getchar();
return ret;
}
const int N=1e6+5;
int n,m,r,lg[N];
struct A
{
int cnt,to[N],nxt[N],he[N],dep[N],f[N][21];
inline void add(int u,int v)
{
to[++cnt]=v,nxt[cnt]=he[u],he[u]=cnt;
}
void dfs(int fa,int u)
{
f[u][0]=fa; dep[u]=(!fa)?0:dep[fa]+1;
for(int i=1;i<=lg[dep[u]];i++)
f[u][i]=f[f[u][i-1]][i-1];
for(int e=he[u];e;e=nxt[e])
{
int v=to[e];
if(v!=fa) dfs(u,v);
}
}
int lca(int u,int v)
{
if(dep[u]>dep[v]) swap(u,v);
while(dep[u]<dep[v])
v=f[v][lg[dep[v]-dep[u]]];
for(int i=lg[dep[u]];i>=0;i--)
if(f[u][i]!=f[v][i])
u=f[u][i],v=f[v][i];
if(u!=v) u=f[u][0];
return u;
}
}tree;
int main()
{
n=read(),m=read(),r=read();
lg[0]=-1;
for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int i=1;i<n;i++)
{
int u=read(),v=read();
tree.add(u,v),tree.add(v,u);
}
tree.dfs(0,r);
while(m--)
{
int u=read(),v=read();
printf("%d\n",tree.lca(u,v));
}
return 0;
}
模板要分开来
求解:
int get(int u,int v)
{
if(dep[u]>dep[v]) swap(u,v);
while(dep[u]<dep[v])
v=f[v][lg[dep[v]-dep[u]]];
for(int i=lg[dep[u]];i>=0;i--)
if(f[u][i]!=f[v][i])
u=f[u][i],v=f[v][i];
if(u!=v) u=f[u][0],v=f[v][0];
return u;
}
构造
void dfs(int fa,int u)
{
dep[u]=(fa==0)?0:dep[fa]+1;
f[u][0]=fa;
for(int i=1;i<=lg[dep[u]];i++)
f[u][i]=f[f[u][i-1]][i-1];
for(int e=he[u];e;e=nxt[e])
{
int v=to[e];
if(fa!=v) dfs(u,v);
}
}