#lCAybttg040407. 1558:聚会
1558:聚会
题目描述
Y 岛有 个城市,有 条道路连接它们,形成一棵树。乘车经过每条道路的费用都是一样的(可视为 单位费用)。
小可可、小卡卡和小 YY 经常想聚会,每次聚会,他们都会选择一个城市,使得三个人到达这个城市的总费用最小。
你需要根据他们每次聚会前所处的位置,为他们选择聚会地点,并输出该地点编号和三人到该地点的总费用。
输入格式
第一行两个正整数, 和 。分别表示城市个数和聚会次数;
后面有 行,每行用两个正整数 和 表示编号为 和编号为 的城市之间有一条路。城市的编号是从 到 的;
再后面有 行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市编号以及小 YY 所在的城市编号。
输出格式
一共有 行,每行两个数 和 ,用一个空格隔开。表示第 次聚会的地点选择在编号为 的城市,总共的费用是经过 条道路所花费的费用(即三人到 的路径长度之和)。
样例
输入样例 1
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
5 2
2 5
4 1
6 0
样例解释
树的结构:
1
|
2
/ \
3 4
|
5
|
6
- 第一次聚会:三人位置 。
- 选择在 聚会: 距离 , 距离 , 距离 ,总费用 。
- 也可以选 :费用 ,不如 优。 是最优解。
- 第二次聚会:三人位置 。
- 选择在 聚会: 距离 (), 距离 , 距离 ,总费用 。
- 第三次聚会:三人位置 。
- 选择在 聚会: 距离 , 距离 , 距离 ,总费用 。
- 第四次聚会:三人位置 。
- 选择在 聚会:总费用 。
数据范围
时间限制:1000 ms
内存限制:524288 KB
提示
这是一个经典问题:树上三点最短路径汇聚点。
对于树上三个点 ,设 为 和 的最近公共祖先,、 同理。可以证明,三人到某点的路径长度之和最小的点 是这三个 LCA 中深度最大的那个点(即最深的 LCA)。
设:
$$p_1 = lca(a,b),\quad p_2 = lca(a,c),\quad p_3 = lca(b,c)$$令 为 中深度最大的节点,则 就是最优聚会地点。
总费用 的计算公式为:
其中 是树上两点距离。
利用 $dist(u,v) = depth[u] + depth[v] - 2 \times depth[lca(u,v)]$ 可以简化计算。
实际上有更直接的公式:
$$C = depth[a] + depth[b] + depth[c] - depth[p_1] - depth[p_2] - depth[p_3]$$这个公式可以通过对称性推导出来。
实现步骤:
- 预处理树的深度 和倍增 LCA 所需信息()。
- 对于每次询问 :
- 求出 ,,。
- 找出深度最大的那个作为 。
- 计算 $C = depth[a] + depth[b] + depth[c] - depth[p_1] - depth[p_2] - depth[p_3]$。
- 输出 和 。
时间复杂度:预处理 ,每次询问 ,总复杂度 ,对于 可以接受。注意输入输出使用快速方式(如 scanf/printf)。