4 条题解
-
0
解题思路
本题要求在花费不超过 x 的条件下,最小化所有路径权值的最大值。
核心观察
路径的权值上限 X 是否可行,可以通过贪心从后往前递推:
- 对于终点 v,其所在路径的权值上限为 X,因此 a_v 必须不超过 X
- 对于其他节点 u,从 u 出发的路径需要满足:a_u + max_child <= X
- 从拓扑序的逆序递推,可以得到每个节点满足约束所需的最小点权
- 计算总花费 sum(max(0, a_i - new_a_i) * c_i),判断是否 <= x
算法步骤
- 预处理拓扑序,建立反向图
- 二分答案 X(上界可取所有 a_i 之和)
- 对每个 X,从后往前递推计算每个节点的最小可行点权
- 验证所需总花费是否 <= x
- 二分找到最小的可行 X
时间复杂度
O((n + m) * log(sum a_i)),在 n <= 500 时完全可接受
参考实现 (Python)
import sys from collections import deque, defaultdict def solve(): input = sys.stdin.readline n, m, x = map(int, input().split()) a = list(map(int, input().split())) c = list(map(int, input().split())) g = [[] for _ in range(n)] indeg = [0] * n for _ in range(m): u, v = map(int, input().split()) u -= 1; v -= 1 g[u].append(v) indeg[v] += 1 order = [] q = deque([i for i in range(n) if indeg[i] == 0]) while q: u = q.popleft() order.append(u) for v in g[u]: indeg[v] -= 1 if indeg[v] == 0: q.append(v) rg = defaultdict(list) for u in range(n): for v in g[u]: rg[v].append(u) def check(limit): need = [0] * n for u in reversed(order): max_child = 0 for v in rg[u]: max_child = max(max_child, need[v]) need[u] = max_child if need[u] + a[u] > limit: need[u] = limit - a[u] if need[u] < 0: need[u] = 0 else: need[u] = 0 total_cost = 0 for i in range(n): reduce = a[i] - need[i] if reduce > 0: total_cost += reduce * c[i] if total_cost > x: return False return total_cost <= x lo, hi = 0, sum(a) while lo < hi: mid = (lo + hi) // 2 if check(mid): hi = mid else: lo = mid + 1 print(lo) if __name__ == '__main__': solve()
信息
- ID
- 468
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者