1 条题解

  • 0
    @ 2025-10-29 19:49:53

    题目大意

    给定一棵 NN 个节点的树,每条边有一个正权值(表示通行时间),树中有 KK 个关键点(志愿者队伍要去的房屋)。对于每个节点 uu(可能的营地位置),需要计算:

    uu 出发,用一辆可以容纳所有队伍的卡车,按照任意顺序访问所有 KK 个关键点(到达每个关键点时放下对应的队伍),并且在最后一个关键点结束(不需要返回营地)所需的最短总时间。

    算法思路

    问题分析

    这是一个树上的最优访问路径问题。关键观察是:

    如果必须返回起点,总时间 = 2 × 最小连通子图的边权和

    由于不需要返回,可以省去从最后一个关键点回到起点的路径

    因此要最大化省去的路径长度,即选择离起点最远的关键点作为最后一个访问点

    核心思想:树形DP + 换根DP

    通过两次DFS遍历来高效计算每个节点作为起点时的答案。

    第一次DFS:自底向上预处理 从叶子节点向根节点遍历,计算:

    sz[u]:以 uu 为根的子树中包含的关键点数量

    g[u][0]、g[u][1]:uu 到子树中第一远、第二远关键点的距离

    res:访问所有关键点所需的最小连通子图的边权和

    对于边 (u,v,w)(u,v,w),如果 vv 的子树有关键点,则该边需要被往返,贡献 2w2w 到总和中

    第二次DFS:自顶向下换根计算 从根节点向叶子节点遍历,维护:

    maxd:从当前节点 uu 出发,到所有关键点中的最远距离

    f[u]:以 uu 为起点时的最优答案

    计算公式:f[u]=2×总边权和maxdf[u] = 2 \times \text{总边权和} - \text{maxd}

    在换根过程中:

    当从父节点 uu 移动到子节点 vv 时,需要更新总边权和 res

    如果 vv 的子树包含所有关键点,则边 (u,v)(u,v) 不再需要经过

    如果 vv 的子树不包含任何关键点,则边 (u,v)(u,v) 需要额外经过

    关键技术细节

    最远点维护:记录每个节点的第一远和第二远关键点距离,用于在换根时计算来自父节点方向的最远距离

    边权和动态更新:在换根DFS中实时调整总边权和,避免重复计算

    关键点判断:通过 sz[u] 快速判断子树中是否包含关键点

    算法复杂度

    时间复杂度:O(N)O(N),两次DFS遍历整棵树

    空间复杂度:O(N)O(N),存储树结构和DP状态数组

    总结

    本题是树形动态规划的经典应用,主要考察:

    问题转化能力:将复杂的最优路径问题转化为最小连通子图边权和与最远点距离的组合

    树形DP设计:设计合适的状态来表示子树信息和最远距离

    换根DP技巧:通过父子节点间状态的传递,高效计算每个节点为根时的答案

    边界情况处理:正确处理子树包含全部关键点或无关键点的情况

    该解法通过 O(N)O(N) 的线性复杂度解决了看似需要 O(N2)O(N^2) 的多源查询问题,体现了树形DP在优化路径问题中的强大威力。这种"预处理+换根"的技术可以广泛应用于需要在树中为每个节点计算特定指标的场景,如最远点、重心、直径等相关问题。

    • 1

    信息

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