1 条题解
-
0
一、题目核心理解
- 给一棵 个节点的树,边有权重 。
- 定义 为树上唯一路径的边权和。
- 最重要的两个城市是 和 (代码中编号为 和 )。
- 我们可以添加一条长度为 的新边 (,且原来没有直接边),使得 尽可能大。
- 对于每个询问的 ,输出最大可能的 。
二、关键观察
1. 原树中 是固定的
设 ,这是不添加任何边时的距离。
2. 添加一条边的影响
添加边 后,新图中 到 的最短路径会变成:
$$\min( cur,\ dist(1,u) + x + dist(v,n),\ dist(1,v) + x + dist(u,n) ) $$因为新边提供了一条“捷径”。
为了使 尽量大,我们希望新路径不要比原路径短太多,甚至希望新路径更长(但不会,因为 且新路径往往更短)。
实际上,添加一条边只会让 减小或不变(因为提供了更短的可能路径)。
但题目要求最大化 ,所以我们要让这个缩短量尽可能小。
三、转化为求最小缩短量
设 $f(u,v) = \min( dist(1,u) + x + dist(v,n),\ dist(1,v) + x + dist(u,n) )$。
添加边后 。
我们希望这个值最大,即希望 尽可能接近 (但不会超过 )。
定义缩短量:
我们要最小化 (因为 固定)。
当 变化时,最优的 可能不同。
四、化简
设 ,。
注意: 当且仅当 在 的路径上。
对于不在该路径上的点,。我们考虑 和 的四种情况,但对称性可简化为:
我们希望这个最小值尽量大,即尽量接近 。
五、关键结论(来自代码)
代码中定义:
- :最小可能的缩短量(与 无关的部分)
- 最终答案:
为什么?
因为最优的 可以写成 的形式,其中 是某个与 无关的常数(由树结构决定)。
于是:但 不能超过 ,所以实际 。
六、如何计算
是树中所有可能选择的 对应的最短路径缩短量的最小值(与 无关的部分)。
代码中通过两次 DFS 计算:
-
第一次 DFS(
calc):- 计算
- 计算子树大小
siz[v],时间戳tin[v], tout[v],用于判断祖先关系 - 父节点
pr[v]
-
第二次 DFS(
dfs):- 沿着 的路径(
isp(u, n-1)判断是否在路径上)进行 - 维护
mn= 当前路径上遇到的最大 (用于计算可能的最小缩短量) - 更新
dif为所有可能的最小值
- 沿着 的路径(
具体地:
- 如果某个不在 路径上的子树大小 ,则
dif = 0(因为可以在该子树内选两个点,使缩短量极小) - 否则,
dfs沿着路径计算:dif = min(dif, max(0, -(mn - d[v])))dif = min(dif, max(0, -(d[pr[p]] - d[v])))- 对于不在路径上的子节点:
dif = min(dif, max(0, -(mn + w - d[v])))
最终
dif是最小可能的缩短量(与 无关的部分)。
七、答案公式
对于询问的 :
如果 ,则 (因为 ,,所以 )。
如果 ,则当 时,;当 时,。
八、复杂度
- DFS 两次:
- 每个询问
- 总复杂度
九、代码对应公式
- 通过
dfs计算 - 输出:
十、图示理解
假设 的路径为 。
添加边 会产生一条新路径 (或反向)。
该路径长度 。
要让它尽量接近 ,就要让 尽量接近 ,即让 和 在 上的投影重叠尽量少,或者让其中一端在 外。就是 的某种转化。
- 1
信息
- ID
- 6634
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者