模板题。。。不多说了很好理解
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAX 200005
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int n,k,to[2*MAX],next[2*MAX],head[MAX],ask_to[2*MAX],ask_next[2*MAX],ask_head[MAX];
int tot=0,Tot=0;
int num[MAX*2],father[MAX],ans[MAX],done[MAX],mark[MAX],root,m;
void add(int from,int To)
{
to[++tot]=To;
next[tot]=head[from];
head[from]=tot;
}
void add_ask(int from,int To,int Num)
{
ask_to[++Tot]=To;
num[Tot]=Num;
ask_next[Tot]=ask_head[from];
ask_head[from]=Tot;
}
int getfather(int x)
{
if(father[x]==x)
return x;
father[x]=getfather(father[x]);
return father[x];
}
void tarjan(int x)
{
done[x]=1;
father[x]=x;
for(int i=head[x];i;i=next[i])
{
int y=to[i];
if(!done[y])
{
tarjan(y);
father[y]=x;
}
}
mark[x]=1;
for(int i=ask_head[x];i;i=ask_next[i])
{
int y=ask_to[i];
if(mark[y])
ans[num[i]]=getfather(y);
}
}
int main()
{
scanf("%d%d",&n,&m);
rep(i,1,n-1)
{
int a1,a2;
scanf("%d%d",&a1,&a2);
add(a1,a2);
father[a2]=a1;
}
rep(i,1,m)
{
int a1,a2;
scanf("%d%d",&a1,&a2);
add_ask(a1,a2,i);
add_ask(a2,a1,i);
}
root=1;
while(father[root])
root=father[root];
tarjan(root);
rep(i,1,m)
printf("%d\n",ans[i]);
return 0;
}