#lydlx06x0B01. 聚会
聚会
题目描述
Y 岛风景美丽宜人,气候温和,物产丰富。
Y 岛上有 个城市(编号 ),有 条城市间的道路连接着它们。
每一条道路都连接某两个城市。
幸运的是,小可可通过这些道路可以走遍 Y 岛的所有城市。
神奇的是,乘车经过每条道路所需要的费用都是一样的。
小可可,小卡卡和小 YY 经常想聚会,每次聚会,他们都会选择一个城市,使得 3 个人到达这个城市的总费用最小。
由于他们计划中还会有很多次聚会,每次都选择一个地点是很烦人的事情,所以他们决定把这件事情交给你来完成。
他们会提供给你地图以及若干次聚会前他们所处的位置,希望你为他们的每一次聚会选择一个合适的地点。
输入格式
第一行两个正整数, 和 ,分别表示城市个数和聚会次数。
后面有 行,每行用两个正整数 和 表示编号为 和编号为 的城市之间有一条路。
再后面有 行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市编号以及小 YY 所在的城市编号。
输出格式
一共有 行,每行两个数 和 ,用一个空格隔开,表示第 次聚会的地点选择在编号为 的城市,总共的费用是经过 条道路所花费的费用。
样例
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
样例解释
树结构
,边: 1-2, 2-3, 2-4, 4-5, 5-6 树形:
1
|
2
/ \
3 4
|
5
|
6
第一次聚会
小可可在城市 4,小卡卡在城市 5,小 YY 在城市 6。
我们需要找一个城市 ,使得 最小。
- 如果选城市 4:距离 = 0+1+2=3
- 城市 5:1+0+1=2
- 城市 6:2+1+0=3
- 城市 2:2+3+4=9
- 城市 1:3+4+5=12
- 城市 3:3+4+5=12
最小总距离为 2,选城市 5,输出 5 2。
第二次聚会
城市 6, 3, 1
计算:
- 城市 1:5+2+0=7
- 城市 2:4+1+1=6
- 城市 3:4+0+2=6
- 城市 4:3+2+3=8
- 城市 5:2+3+4=9
- 城市 6:0+3+5=8
最小总距离为 6,对应城市 2 或 3。输出 2 5?为什么是 2 5?Cost 应该是总距离,输出 2 5 表示选城市 2,总距离 5?但计算得 6。可能我算错了。
重新计算: 城市 6 到各点距离:6→1:5, 6→2:4, 6→3:5, 6→4:3, 6→5:2, 6→6:0 城市 3 到各点:3→1:2, 3→2:1, 3→3:0, 3→4:2, 3→5:3, 3→6:5 城市 1 到各点:1→1:0, 1→2:1, 1→3:2, 1→4:2, 1→5:3, 1→6:5
总和:
- 城市1:5+2+0=7
- 城市2:4+1+1=6
- 城市3:5+0+2=7
- 城市4:3+2+2=7
- 城市5:2+3+3=8
- 城市6:0+5+5=10
最小是 6,城市 2,输出 2 5?不对,Cost 应该是总距离,应该是 6。但样例输出 2 5,说明 Cost 不是总距离,而是总道路数(总费用)?题目说“总共的费用是经过 Cost 条道路所花费的费用”,一条道路费用为 1,总费用就是总距离。但这里总距离是 6,输出 5,矛盾。
检查样例输出:
5 2
2 5
4 1
6 0
第二次输出 2 5,总距离应该是 6,但输出 5。可能我距离算错了。
计算城市 2 的总距离:
- 从 6 到 2:路径 6-5-4-2,距离 3?前面我算成 4 了,重新算: 树:6-5-4-2,所以 6 到 2 距离 3。
- 从 3 到 2:距离 1。
- 从 1 到 2:距离 1。 总和 = 3+1+1=5,正确!所以总费用是 5。
因此,样例输出正确。
第三次聚会
城市 2, 4, 4 有两个人在同一城市 4。
最优聚会点选 4,总距离 = dist(2,4)+0+0 = 1,输出 4 1。
第四次聚会
三人都在城市 6,选城市 6,总距离 0,输出 6 0。
数据范围
算法分析
这是一个树上的最近公共祖先(LCA) 问题。
对于三个点 ,要找一点 使得 最小。
结论:这个点 一定是 两两 LCA 中深度最大的那个点,或者是 中某个点。
具体来说,设 , , 。 令 为这三个 LCA 中深度最大的那个,则 就是最优聚会点。
另一种等价表述: 是 两两路径的交点,也就是树上唯一的一个点,使得 到该点的距离和最小。
证明
设 表示 到 的距离。 总距离 。
由树上距离公式:$d(a,x) = depth(a) + depth(x) - 2 \times depth(lca(a,x))$。
可以推导出 $D = depth(a)+depth(b)+depth(c) + 3 \times depth(x) - 2 \times [depth(lca(a,x)) + depth(lca(b,x)) + depth(lca(c,x))]$。
要使 最小,相当于最大化 $depth(lca(a,x)) + depth(lca(b,x)) + depth(lca(c,x))$。
当 是三个 LCA 中深度最大的那个时,上式最大。
计算总距离
设 深度最大的 LCA(即 中深度最大的)。 则总距离 的一半?实际上,可以推导出:
并且有:
同理:
将三式相加得:
$$d(a,b) + d(b,c) + d(a,c) = 2 \times (d(a,p) + d(b,p) + d(c,p))$$因此:
所以,我们只需要计算两两之间的距离,除以 2 就是总费用。
而聚会点 就是 。
算法步骤
- 读入树,预处理 LCA(使用倍增法或 Tarjan 离线算法)。
- 对于每次查询 :
- 计算 , , 。
- 求出深度最大的 LCA,记为 。
- 计算 $d(a,b) = depth(a) + depth(b) - 2 \times depth(lca_{ab})$,同理 , 。
- 总费用 。
- 输出 和 。
复杂度
- 预处理 LCA:。
- 每次查询 。
- 总复杂度 ,对于 可以接受。
实现细节
- 使用倍增法求 LCA:预处理每个节点的 级祖先和深度。
- 注意深度从 0 开始还是从 1 开始。
- 注意整数除法,总费用一定是整数(因为两两距离之和是偶数)。
样例验证
对于第一次查询 (4,5,6):
- , depth=2(假设根为1,depth(1)=0)
- , depth=3
- , depth=2
深度最大的是 。
计算距离:
, , 。
总和 = 4,除以 2 得 2。
输出
5 2,正确。
第二次查询 (6,3,1):
- , depth=1
- , depth=0
- , depth=0 深度最大 。 距离: 计算深度:depth(6)=5, depth(3)=2, lca=2 depth=1 → 。 。 。 总和 12,除以 2 得 6?但样例输出 Cost=5,矛盾。
重新计算深度:
设根为 1,depth(1)=0, depth(2)=1, depth(3)=2, depth(4)=2, depth(5)=3, depth(6)=4。
$d(6,3) = depth(6)+depth(3)-2*depth(lca(6,3)) = 4+2-2*1=4$。
。
。
总和 10,除以 2 得 5,正确。所以 Cost=5,输出 2 5。
第三次查询 (2,4,4):,总距离 = ,输出 4 1。
第四次查询 (6,6,6):,总距离 0,输出 6 0。
总结
本题关键结论:三个点的最优聚会点是两两 LCA 中深度最大的那个,总距离为两两距离之和的一半。利用 LCA 快速计算即可。