1 条题解

  • 0
    @ 2025-10-28 10:52:26

    题意回顾

    给定一棵 nn 个节点的树,边带权(权值可为负)。
    要选出若干条长度恰好为 44 的简单链(即包含 55 个节点、44 条边),且这些链在点上不相交(边自然也不相交)。
    目标是最大化所选链的边权总和。

    数据范围:n2×105n \leq 2\times 10^5,边权绝对值 109\leq 10^9


    关键难点

    1. 长度恰好为 4:这意味着一条链涉及 5 个节点,在树上形态比较固定。
    2. 链不交:选择的链不能共享节点,是点不交路径覆盖的一种特殊情形。
    3. 边权可负:需要判断选一条链是否划算。

    树形 DP 状态设计

    由于链长度固定为 44,我们可以枚举链在树上的形态。长度为 44 的链在树上有两种主要形态:

    • 直链u0u1u2u3u4u_0 - u_1 - u_2 - u_3 - u_4(5 个节点依次相连)
    • 星形链:长度 4 的链在树上只能是直链形态,因为树没有环。

    所以唯一形态就是 5 个节点连成一条线。


    DP 思路

    dp[u][t]dp[u][t] 表示在 uu 的子树中,uu 所处的链的未完成部分长度tt 时的最大收益。

    这里 tt 的含义:

    • t=0t=0uu 不在任何链中,或 uu 是某条完整链的端点(链已结束)
    • t=1t=1uu 是某条链的一端,该链已包含 1 条边(还需 3 条边完成)
    • t=2t=2uu 是某条链的一端,该链已包含 2 条边(还需 2 条边完成)
    • t=3t=3uu 是某条链的一端,该链已包含 3 条边(还需 1 条边完成)
    • t=4t=4uu 是某条链的一端,该链已包含 4 条边(链完成)

    由于链长恰好 4,所以 tt 取值 0,1,2,3,40,1,2,3,4


    状态转移

    考虑节点 uu 和它的一个子节点 vv,边权 ww

    1. 不将边 (u,v)(u,v) 用于链

    那么 vv 的子树独立处理,uu 的状态不变,加上 vv 子树的最佳收益(即 dp[v][0]dp[v][0])。

    2. 将边 (u,v)(u,v) 用于延长链

    • 如果 uu 当前状态为 tt,加入这条边后状态变为 t+1t+1(如果 t<4t<4
    • 收益增加 ww
    • 同时 vv 的状态要从 tt' 转移来,且 uuvv 的状态要匹配

    更具体地,枚举 uu 的状态 iivv 的状态 jj,尝试用边 (u,v)(u,v) 连接:

    • 如果 i=0,j=3i=0, j=3:用这条边连接后形成完整链(012340\to 1\to 2\to 3\to 4vv 子树中已完成 3 条边,加上 (u,v)(u,v) 完成第 4 条),收益 w+dp[v][3]w + dp[v][3]uu 新状态为 00(链完成)。
    • 如果 i=1,j=2i=1, j=2:连接后状态变为 44(完成链),收益 w+dp[v][2]w + dp[v][2]uu 新状态 00
    • 如果 i=2,j=1i=2, j=1:同理,收益 w+dp[v][1]w + dp[v][1]uu 新状态 00
    • 如果 i=3,j=0i=3, j=0:收益 w+dp[v][0]w + dp[v][0]uu 新状态 00

    以及未完成链的延长:

    • i=0,j=0i=0, j=0:开始新链,uu 状态变为 11,收益 w+dp[v][0]w + dp[v][0]
    • i=1,j=0i=1, j=0:延长链,uu 状态变为 22,收益 w+dp[v][0]w + dp[v][0]
    • i=2,j=0i=2, j=0uu 状态变为 33,收益 w+dp[v][0]w + dp[v][0]
    • i=3,j=0i=3, j=0uu 状态变为 44,收益 w+dp[v][0]w + dp[v][0]

    合并多个子树

    节点 uu 可能有多个子节点,我们需要合并它们的贡献。
    因为链不能分叉,所以 uu 最多连接两个子节点用于同一条链(作为链上的一个点有度最多 2)。

    实际上,uu 在一条链中最多连接 2 个子节点(一进一出),其他子节点必须独立处理。

    因此合并时,对每个子节点 vv,我们考虑:

    • 不连接 (u,v)(u,v):贡献 dp[v][0]dp[v][0]
    • 连接 (u,v)(u,v) 并延长链:根据当前 uu 状态和 vv 状态更新

    这是一个经典的树形 DP 合并技巧,需要维护 uu 的各个状态的最大值,并依次用每个子节点更新。


    算法步骤

    1. 任选根节点(如 1)进行 DFS
    2. 初始化 dp[u][0]=0dp[u][0]=0,其余 dp[u][t]=dp[u][t]=-\infty
    3. uu 的每个子节点 vv(边权 ww):
      • 创建临时数组 new_dpnew\_dp 初始为 -\infty
      • 枚举 uu 的当前状态 iivv 的可能状态 jj,考虑:
        • 不连接:new_dp[i]=max(new_dp[i],dp[u][i]+dp[v][0])new\_dp[i] = \max(new\_dp[i], dp[u][i] + dp[v][0])
        • 连接并可能完成链:根据上述规则更新
      • new_dpnew\_dp 复制给 dp[u]dp[u]
    4. 最终答案:max(dp[root][0],dp[root][4])\max(dp[root][0], dp[root][4])t=4t=4 表示以 root 为端点的完整链)

    复杂度分析

    • 状态数:每个节点 55 个状态
    • 合并时枚举 i,ji,j5×5=255\times 5=25
    • 总复杂度:O(25n)=O(n)O(25n) = O(n),可过 n2×105n\leq 2\times 10^5

    总结

    本题的关键在于:

    1. 识别链长固定为 44 的特殊性
    2. 设计状态 dp[u][t]dp[u][t] 表示 uu 在链中的位置
    3. 分类讨论连接边是否用于链,以及是否完成链
    4. 使用临时数组正确合并多个子树的贡献

    通过精细的状态设计和转移,可以在 O(n)O(n) 时间内求出最大收益,解决大规模数据。

    • 1

    信息

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