一本通1558聚会
1558:聚会
题目描述
原题来自:AHOI 2008
Y 岛风景美丽宜人,气候温和,物产丰富。Y 岛上有 NN 个城市,有 N-1 条城市间的道路连接着它们。每一条道路都连接某两个城市。幸运的是,小可可通过这些道路可以走遍 Y 岛的所有城市。神奇的是,乘车经过每条道路所需要的费用都是一样的。
小可可,小卡卡和小 YY 经常想聚会,每次聚会,他们都会选择一个城市,使得三个人到达这个城市的总费用最小。
由于他们计划中还会有很多次聚会,每次都选择一个地点是很烦人的事情,所以他们决定把这件事情交给你来完成。他们会提供给你地图以及若干次聚会前他们所处的位置,希望你为他们的每一次聚会选择一个合适的地点。
输入格式
第一行两个正整数,N 和 M。分别表示城市个数和聚会次数;
后面有 N−1 行,每行用两个正整数 A 和 B 表示编号为 A 和编号为 B 的城市之间有一条路。城市的编号是从 1 到 N 的;
再后面有 M 行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市编号以及小 YY 所在的城市编号。
输出格式
一共有 M 行,每行两个数 P 和 C,用一个空格隔开。表示第 i 次聚会的地点选择在编号为 P 的城市,总共的费用是经过 C 条道路所花费的费用。
样例
样例输入
6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
样例输出
5 2
2 5
4 1
6 0
数据范围与提示
40% 的数据中,1≤N,M≤2×10^3;
100% 的数据中,1≤N,M≤5×10^5。
sol:只要无耻的抄结论就可以了:
求三个结点到一个结点距离之和最小的结点以及距离和
求出两两lca,其中有两个相同,答案则为另一个,画画图就可以理解
#include <bits/stdc++.h> using namespace std; const int N=100005,M=200005; int n,m; struct Tree { int tot,Next[M],to[M],head[N]; inline void add(int x,int y) { Next[++tot]=head[x]; to[tot]=y; head[x]=tot; return; } int F[N][23],Depth[N]; inline void dfs(int x,int fa) { F[x][0]=fa; Depth[x]=Depth[fa]+1; int i; for(i=head[x];i;i=Next[i]) if(to[i]!=fa) { dfs(to[i],x); } return; } inline void Pre() { int i,j; dfs(1,1); for(i=1;i<=19;i++) { for(j=1;j<=n;j++) F[j][i]=F[F[j][i-1]][i-1]; } return; } inline int Ask_Lca(int x,int y) { int i; if(Depth[x]<Depth[y]) swap(x,y); for(i=19;~i;i--) if(Depth[F[x][i]]>=Depth[y]) { x=F[x][i]; } if(x==y) return x; for(i=19;~i;i--) if(F[x][i]!=F[y][i]) { x=F[x][i]; y=F[y][i]; } return F[x][0]; } inline void Solve(int a,int b,int c) { int ab=Ask_Lca(a,b),ac=Ask_Lca(a,c),bc=Ask_Lca(b,c),pp; if(ab==ac) pp=bc; else if(ab==bc) pp=ac; else pp=ab; printf("%d %d\n",pp,Depth[a]+Depth[b]+Depth[c]-Depth[ab]-Depth[ac]-Depth[bc]); return; } }T; int main() { int i; scanf("%d%d",&n,&m); for(i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); T.add(x,y); T.add(y,x); } T.Pre(); for(i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); T.Solve(a,b,c); } return 0; } /* 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 output 5 2 2 5 4 1 6 0 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!