1 条题解

  • 0
    @ 2026-4-21 18:40:48

    一、题目核心理解

    • 给一棵 nn 个节点的树,边有权重 wiw_i
    • 定义 dist(u,v)dist(u,v) 为树上唯一路径的边权和。
    • 最重要的两个城市是 11nn(代码中编号为 00n1n-1)。
    • 我们可以添加一条长度为 xx 的新边 (u,v)(u,v)uvu \ne v,且原来没有直接边),使得 dist(1,n)dist(1, n) 尽可能大。
    • 对于每个询问的 xx,输出最大可能的 dist(1,n)dist(1,n)

    二、关键观察

    1. 原树中 dist(1,n)dist(1,n) 是固定的

    cur=dist(1,n)cur = dist(1,n),这是不添加任何边时的距离。

    2. 添加一条边的影响

    添加边 (u,v)(u,v) 后,新图中 11nn 的最短路径会变成:

    $$\min( cur,\ dist(1,u) + x + dist(v,n),\ dist(1,v) + x + dist(u,n) ) $$

    因为新边提供了一条“捷径”。

    为了使 dist(1,n)dist(1,n) 尽量大,我们希望新路径不要比原路径短太多,甚至希望新路径更长(但不会,因为 x1x \ge 1 且新路径往往更短)。

    实际上,添加一条边只会让 dist(1,n)dist(1,n) 减小或不变(因为提供了更短的可能路径)。
    但题目要求最大化 dist(1,n)dist(1,n),所以我们要让这个缩短量尽可能小


    三、转化为求最小缩短量

    设 $f(u,v) = \min( dist(1,u) + x + dist(v,n),\ dist(1,v) + x + dist(u,n) )$。

    添加边后 dist(1,n)=min(cur, f(u,v))dist(1,n) = \min( cur,\ f(u,v) )

    我们希望这个值最大,即希望 f(u,v)f(u,v) 尽可能接近 curcur(但不会超过 curcur)。

    定义缩短量:

    Δ(u,v)=curf(u,v)\Delta(u,v) = cur - f(u,v)

    我们要最小化 Δ(u,v)\Delta(u,v)(因为 curcur 固定)。

    xx 变化时,最优的 (u,v)(u,v) 可能不同。


    四、化简 Δ(u,v)\Delta(u,v)

    du=dist(1,u)d_u = dist(1,u)du=dist(u,n)d'_u = dist(u,n)

    注意:du+du=curd_u + d'_u = cur 当且仅当 uu1n1 \to n 的路径上。
    对于不在该路径上的点,du+du>curd_u + d'_u > cur

    我们考虑 uuvv 的四种情况,但对称性可简化为:

    f(u,v)=min(du+x+dv, dv+x+du)f(u,v) = \min( d_u + x + d'_v,\ d_v + x + d'_u )

    我们希望这个最小值尽量大,即尽量接近 curcur


    五、关键结论(来自代码)

    代码中定义:

    • difdif:最小可能的缩短量(与 xx 无关的部分)
    • 最终答案:min(cur, curdif+x)\min(cur,\ cur - dif + x)

    为什么?
    因为最优的 Δ(u,v)\Delta(u,v) 可以写成 difxdif - x 的形式,其中 difdif 是某个与 xx 无关的常数(由树结构决定)。
    于是:

    f(u,v)=cur(difx)=curdif+xf(u,v) = cur - (dif - x) = cur - dif + x

    f(u,v)f(u,v) 不能超过 curcur,所以实际 dist(1,n)=min(cur, curdif+x)dist(1,n) = \min(cur,\ cur - dif + x)


    六、如何计算 difdif

    difdif 是树中所有可能选择的 (u,v)(u,v) 对应的最短路径缩短量的最小值(与 xx 无关的部分)。

    代码中通过两次 DFS 计算:

    1. 第一次 DFS(calc):

      • 计算 d[v]=dist(0,v)d[v] = dist(0, v)
      • 计算子树大小 siz[v],时间戳 tin[v], tout[v],用于判断祖先关系
      • 父节点 pr[v]
    2. 第二次 DFS(dfs):

      • 沿着 1n1 \to n 的路径(isp(u, n-1) 判断是否在路径上)进行
      • 维护 mn = 当前路径上遇到的最大 d[v]+wd[v] + w(用于计算可能的最小缩短量)
      • 更新 dif 为所有可能的最小值

    具体地:

    • 如果某个不在 1n1 \to n 路径上的子树大小 >1>1,则 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最小可能的缩短量(与 xx 无关的部分)。


    七、答案公式

    对于询问的 xx

    ans=min(cur, curdif+x)\text{ans} = \min( cur,\ cur - dif + x )

    如果 dif=0dif = 0,则 ans=min(cur, cur+x)=cur\text{ans} = \min(cur,\ cur + x) = cur(因为 x1x \ge 1cur+x>curcur + x > cur,所以 ans=cur\text{ans}=cur)。

    如果 dif>0dif > 0,则当 xdifx \ge dif 时,ans=cur\text{ans} = cur;当 x<difx < dif 时,ans=curdif+x\text{ans} = cur - dif + x


    八、复杂度

    • DFS 两次:O(n)O(n)
    • 每个询问 O(1)O(1)
    • 总复杂度 O(n+m)O(n + m)

    九、代码对应公式

    • cur=d[n1]cur = d[n-1]
    • difdif 通过 dfs 计算
    • 输出:min(cur, curdif+x)\min(cur,\ cur - dif + x)

    十、图示理解

    假设 1n1 \to n 的路径为 PP
    添加边 (u,v)(u,v) 会产生一条新路径 1uvn1 \to u \to v \to n(或反向)。
    该路径长度 =du+x+dv= d_u + x + d'_v
    要让它尽量接近 curcur,就要让 du+dvd_u + d'_v 尽量接近 curcur,即让 uuvvPP 上的投影重叠尽量少,或者让其中一端在 PP 外。

    difdif 就是 curmaxu,vmin(du+dv, dv+du)cur - \max_{u,v} \min(d_u + d'_v,\ d_v + d'_u) 的某种转化。


    • 1

    信息

    ID
    6634
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者