良心题2333
三个点两两求一遍就行,最小肯定是在某2个点的lca处,(肯定让第三个人去找2个人,不能让2个人一起去找第三个人233)
1 #include<bits/stdc++.h> 2 #define N 500005 3 #define M 10000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 11 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 12 return x*f; 13 } 14 struct node{ 15 int to,next; 16 }e[N<<1]; 17 int head[N],cnt; 18 int fa[N][20],deep[N],n,m; 19 void insert(int x, int y){e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;} 20 void dfs(int x) 21 { 22 for (int i=1; i<=19; i++) 23 if (deep[x]>=(1<<i)) 24 fa[x][i]=fa[fa[x][i-1]][i-1]; 25 else break; 26 for (int i=head[x];i;i=e[i].next) 27 { 28 if (e[i].to==fa[x][0]) continue; 29 fa[e[i].to][0]=x; 30 deep[e[i].to]=deep[x]+1; 31 dfs(e[i].to); 32 } 33 } 34 int lca(int x, int y) 35 { 36 if (deep[x]<deep[y]) swap(x,y); 37 int t=deep[x]-deep[y]; 38 for (int i=0; (1<<i)<=t ; i++) 39 if (t&(1<<i)) x=fa[x][i]; 40 for (int i=19; i>=0; i--) 41 if (fa[x][i]!=fa[y][i]) 42 x=fa[x][i],y=fa[y][i]; 43 if (x==y) return x; 44 return fa[x][0]; 45 } 46 int lca_cost(int x, int y) 47 { 48 int sum=0; 49 if (deep[x]<deep[y]) swap(x,y); 50 int t=deep[x]-deep[y]; 51 for (int i=0; (1<<i)<=t ; i++) 52 if (t&(1<<i)) x=fa[x][i],sum+=(1<<i); 53 for (int i=19; i>=0; i--) 54 if (fa[x][i]!=fa[y][i]) 55 x=fa[x][i],y=fa[y][i],sum+=(1<<i)*2; 56 if (x==y) return sum; 57 return sum+2; 58 } 59 int main() 60 { 61 n=ra(); m=ra(); 62 for (int i=1; i<n; i++) 63 { 64 int x=ra(),y=ra(); 65 insert(x,y); insert(y,x); 66 } 67 dfs(1); 68 for (int i=1; i<=m; i++) 69 { 70 int x=ra(),y=ra(),z=ra(); 71 int ans1=lca_cost(x,y)+lca_cost(lca(x,y),z); 72 int ans2=lca_cost(x,z)+lca_cost(lca(x,z),y); 73 int ans3=lca_cost(y,z)+lca_cost(lca(y,z),x); 74 int ans=min(min(ans1,ans2),ans3); 75 if (ans==ans1) printf("%d ",lca(x,y)); 76 else if (ans==ans2) printf("%d ",lca(x,z)); 77 else if (ans==ans3) printf("%d ",lca(y,z)); 78 printf("%d ",ans); 79 } 80 }