Description
Input
Output
Sample Input
6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
Sample Output
5 2
2 5
4 1
6 0
HINT
Source
题解:首先由题意知这是一颗树,先考虑2个点的情况,p点必为lca(a,b),拓展到三个点,那么答案应该在lca(a,b) lca(a,c) lca(b,c)中选出一个,那么此题就解决了
先枚举在哪一个lca,然后利用在之前求过的d数组(保存节点的层数)来快速的算出答案,3各种选最小值即可
程序:
#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
int n,m,u,v,i,len,k,j,ans,mi;
int st[500005][35];
int d[500005];
int head[500005];
int a[40];
int f[5];
struct node{
int u,v,next;
node(){
u=v=0;next=-1;
}
node(int x,int y,int z){
u=x;v=y;next=z;
}
} e[1500005];
struct qwe{
int x,deep,f;
qwe(){
x=deep=f=0;
}
qwe(int a,int s,int d){
x=a;deep=s;f=d;
}
};
void add(int u,int v){
len++;
e[len]=node(u,v,head[u]);
head[u]=len;
}
void dfs(){
int deep,x,f;
queue <qwe> q;
q.push(qwe(1,0,0));
d[0]=-1;
while(!q.empty()){
deep=q.front().deep;
x=q.front().x;
f=q.front().f;
q.pop();
d[x]=deep;
st[x][0]=f;
for(int i=1;a[i]<=deep;i++)
st[x][i]=st[st[x][i-1]][i-1];
for(int i=head[x];i!=-1;i=e[i].next)
if(e[i].v!=f)
q.push(qwe(e[i].v,deep+1,x));
}
}
int lca(int x,int y){
int i;
if(x==y)
return x;
//printf("1--%d %d\n",x,y);
if(d[x]>d[y])
swap(x,y);
//printf("2--%d %d\n",x,y);
for(i=30;i>=0;i--)
if(d[st[y][i]]>=d[x])
y=st[y][i];
//printf("3--%d %d\n",x,y);
if(x==y)
return x;
for(i=30;i>=0;i--)
if(st[x][i]!=st[y][i]){
x=st[x][i];
y=st[y][i];
}
//printf("4--%d %d\n\n",x,y);
return st[x][0];
}
int main(){
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
head[i]=-1;
a[0]=1;
for(i=1;i<=30;i++)
a[i]=a[i-1]*2;
for(i=1;i<n;i++){
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
dfs();
/*for(i=1;i<=n;i++){
for(int j=0;a[j]<=d[i];j++)
printf("%d ",st[i][j]);
puts("");
}
printf("%d\n",lca(4,6));*/
while(m--){
ans=2147483647;
for(j=1;j<=3;j++)
scanf("%d",&f[j]);
for(i=1;i<3;i++)
for(j=i+1;j<=3;j++){
k=6-i-j;
//printf("%d\n",k);
u=lca(f[i],f[j]);
//printf("uv---%d %d\n",u,k);
v=lca(u,f[k]);
//printf("uv---%d %d\n",u,v);
if(ans>(d[f[i]]+d[f[j]]+d[f[k]]-d[u]-2*d[v])){
ans=(d[f[i]]+d[f[j]]+d[f[k]]-d[u]-2*d[v]);
mi=u;
}
}
printf("%d %d\n",mi,ans);
}
return 0;
}