#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct data{
int next,to;
}sz[1000010];
struct Node{
int fa,son,size,deep,top,num,end;
}tree[500010];
int head[500010];
int n,m,r,cnt,tot;
void update(int start,int end){
sz[++cnt].next=head[start];
sz[cnt].to=end;
head[start]=cnt;
}
void dfs1(int u){
tree[u].size=1;
tree[u].son=0;
for(int i=head[u];i;i=sz[i].next)
if(sz[i].to!=tree[u].fa){
tree[sz[i].to].fa=u;
tree[sz[i].to].deep=tree[u].deep+1;
dfs1(sz[i].to);
tree[u].size+=tree[sz[i].to].size;
if(tree[sz[i].to].size>tree[tree[u].son].size) tree[u].son=sz[i].to;
}
return;
}
void dfs2(int u,int tp){
tree[u].top=tp;
tree[u].num=++tot;
if(tree[u].son){
dfs2(tree[u].son,tp);
for(int i=head[u];i;i=sz[i].next)
if(sz[i].to!=tree[u].fa&&sz[i].to!=tree[u].son) dfs2(sz[i].to,sz[i].to);
}
tree[u].end=tot;
return;
}
int lca(int a,int b){
int f1=tree[a].top,f2=tree[b].top;
while(f1!=f2){
if(tree[f1].deep>tree[f2].deep){
a=tree[f1].fa;
f1=tree[a].top;
}
else{
b=tree[f2].fa;
f2=tree[b].top;
}
}
if(tree[a].deep<tree[b].deep) return a;
else return b;
}
int main(){
freopen("5.in","r",stdin);
freopen("5.out","w",stdout);
scanf("%d%d%d",&n,&m,&r);
int u,v;
for(int i=1;i<=n;i++){
scanf("%d%d",&u,&v);
update(u,v);
update(v,u);
}
dfs1(r);
dfs2(r,r);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
}
return 0;
}
树剖LCA
最新推荐文章于 2022-11-01 18:19:03 发布