1 条题解

  • 0
    @ 2025-10-21 8:01:46

    问题分析

    本题是一道基于树结构贪心算法的路径优化问题,核心任务是在一棵树上找到最多的节点,使得从两个指定起点(XY)到达这些节点的路径总代价不超过给定阈值K。算法需要结合深度优先搜索(DFS)、优先队列和贪心策略,高效计算符合条件的最大节点数量。

    算法思路

    1. 树结构与距离计算

    • 树的表示:使用邻接表存储树的边,frnevw数组共同构成邻接表,其中w存储边的权重。
    • 距离计算:通过两次DFS分别计算从起点X到所有节点的距离da[],以及从起点Y到所有节点的距离db[]
      • dfs0(X, 0, 0, da):以X为根,计算每个节点到X的距离并存储在da中。
      • dfs0(Y, 0, 0, db):以Y为根,计算每个节点到Y的距离并存储在db中。

    2. 初始贪心策略(count0函数)

    • 核心思想:使用优先队列(最小堆)模拟从XY同时扩展节点的过程,每次选择代价最小的路径扩展,直到总代价超过K
    • 优先级队列:存储(当前总代价, 节点),其中节点为正表示从X扩展,为负表示从Y扩展。
    • 扩展规则:每次弹出代价最小的节点,累加计数,并将其未访问的邻接节点按新代价(从XY到该邻接节点的距离)加入队列。
    • 终止条件:队列顶部节点的代价超过剩余K时停止,返回累计的节点数量。

    3. 优化贪心策略(cal函数)

    • 节点分类:将节点分为两类:
      • 一类是2*a < bada[i]bdb[i],已交换确保a ≤ b),直接拆分路径代价为ab-a
      • 另一类是2*a ≥ b,保留为(a, b)结构,用于后续组合优化。
    • 排序与前缀和
      • 对拆分后的代价数组v2排序,对保留的(a, b)b排序,并计算前缀和su
      • 预计算最优组合的最小代价h1,用于快速查询不同数量节点的最小总代价。
    • 组合优化:通过双指针遍历,找到拆分代价与保留代价的最优组合,使得总代价不超过K且节点数量最多。

    4. 结果融合

    • 比较初始贪心策略(count0)和优化贪心策略(cal)的结果,取最大值作为最终答案。

    关键公式与复杂度

    1. 距离计算

      • 节点iX的距离:da[i] = da[父节点] + 边权重
      • 节点iY的距离:db[i] = db[父节点] + 边权重 时间复杂度:O(N)(两次DFS遍历树)。
    2. 初始贪心扩展

      • 每个节点最多入队一次,优先队列操作时间复杂度为O(N log N)
    3. 优化贪心策略

      • 排序操作:O(N log N)(对拆分代价和保留代价排序)。
      • 双指针组合查询:O(N)。 总时间复杂度:O(N log N)
    4. 整体复杂度O(N log N),其中N为树的节点数量,适合处理N ≤ 2×10^5的规模。

    代码解析

    模块 功能描述
    树的构建 addb函数构建邻接表,存储树的边和权重。
    距离计算 dfs0函数通过DFS计算节点到起点的距离。
    初始贪心 count0函数使用优先队列扩展节点,计算最大数量。
    优化贪心 cal函数通过分类、排序和组合优化,计算更优解。
    主函数 整合所有步骤,返回两种策略中的最大值作为答案。

    算法的核心是结合两种贪心策略:初始策略通过优先队列模拟扩展过程,优化策略通过分类和组合进一步挖掘最优解,最终在保证效率的前提下得到最大节点数量。

    • 1

    信息

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