题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1832
省选出出了CF的感觉.....
显然一发贪心,如果两个点显然就是他们的$LCA$(不在一条链上的情况),第三个点不就直接走到这个$LCA$么,考虑$3$种分别组合的情况即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 500100 10 #define llg int 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,f[maxn][21],deep[maxn]; 13 vector<llg>a[maxn]; 14 15 void dfs(llg x,llg fa) 16 { 17 llg w=a[x].size(),v; 18 deep[x]=deep[fa]+1,f[x][0]=fa; 19 for (llg i=0;i<w;i++) 20 { 21 v=a[x][i]; 22 if (v==fa) continue; 23 dfs(v,x); 24 } 25 } 26 27 void make_f() 28 { 29 for (llg j=1;j<=20;j++) 30 for (llg i=1;i<=n;i++) 31 f[i][j]=f[f[i][j-1]][j-1]; 32 } 33 34 llg find(llg x,llg y) 35 { 36 if (deep[x]<deep[y]) swap(x,y); 37 for (llg i=20;i>=0;i--) 38 if (deep[f[x][i]]>=deep[y]) 39 x=f[x][i]; 40 if (x==y) return x; 41 for (llg i=20;i>=0;i--) 42 if (f[x][i]!=f[y][i]) 43 x=f[x][i],y=f[y][i]; 44 return f[x][0]; 45 } 46 47 void init() 48 { 49 llg x,y; 50 cin>>n>>m; 51 for (llg i=1;i<n;i++) 52 { 53 scanf("%d%d",&x,&y); 54 a[x].push_back(y),a[y].push_back(x); 55 } 56 dfs(1,0); 57 make_f(); 58 } 59 60 llg dis(llg x,llg y){return deep[x]+deep[y]-deep[find(x,y)]*2;} 61 62 int main() 63 { 64 yyj("bzoj1832"); 65 init(); 66 llg x,y,z,val,po,ans; 67 while (m--) 68 { 69 ans=0x7fffffff; 70 scanf("%d%d%d",&x,&y,&z); 71 72 val=dis(x,y)+dis(find(x,y),z); 73 if (val<ans) {ans=val,po=find(x,y);} 74 75 val=dis(z,y)+dis(find(z,y),x); 76 if (val<ans) {ans=val,po=find(z,y);} 77 78 val=dis(x,z)+dis(find(x,z),y); 79 if (val<ans) {ans=val,po=find(x,z);} 80 81 printf("%d %d\n",po,ans); 82 } 83 return 0; 84 }