满足条件的点一定在两点lca上,枚举三个lca即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
char ch=getchar();int f=0;
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
{f=(f<<1)+(f<<3)+ch-'0';
ch=getchar();
}
return f;
}
int x1,x2;
struct node
{
int to;
int next;
}edge[1000005];
int tot=0,head[500005],anc[500005][22],n,m,root,dep[500005];
void add(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
bool vis[500005];
void dfs(int x)
{
vis[x]=1;
for(int i=1;i<=20;i++)
{
if(dep[x]<(1<<i))
break;
anc[x][i]=anc[anc[x][i-1]][i-1];
}
for(int i=head[x];i!=-1;i=edge[i].next)
{
int now=edge[i].to;
if(vis[now])
continue;
dep[now]=dep[x]+1;
anc[now][0]=x;
dfs(now);
}
}
int l(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
x1=x2=0;
for(int i=20;i>=0;i--)
{
if(dep[anc[x][i]]>=dep[y])
x=anc[x][i],x1+=(1<<i);
}
if(x==y) return x;
for(int i=20;i>=0;i--)
{
if(anc[x][i]!=anc[y][i])
{
x=anc[x][i];
y=anc[y][i];
x2+=(1<<i);
}
}x2+=1,x1+=x2;
return anc[x][0];
}
int main()
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
int a,b,c;
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
root=1;
dep[root]=1;
dfs(root);
int temp,pla,ans;
/*for(int i=1;i<=n;i++)
{
for(int j=0;j<=5;j++)
printf("%d ",anc[i][j]);
puts("");
}*/
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
int lca=l(a,b),temp=x1+x2;
l(lca,c);
temp+=x1+x2;
ans=temp,pla=lca;
lca=l(a,c),temp=x1+x2;
l(lca,b);
temp+=x1+x2;
if(ans>temp)ans=temp,pla=lca;
lca=l(b,c),temp=x1+x2;
l(lca,a);
temp+=x1+x2;
if(ans>temp)ans=temp,pla=lca;
printf("%d %d\n",pla,ans);
}
return 0;
}