Loading

AT_arc098_d Donation

考虑一个点 \(u\) 被经过的若干次,肯定是最后一次再捐钱。

\(T\) 是当前时刻的存款,在 \(u\)任意时刻,我们只需要保证 \(T \geq a_u - b_u\) 即可。(任意时刻的意思是,捐钱之后的 \(T\) 也要满足 \(T \geq a_u - b_u\)

Q1:我们进入一个点不是要保证 \(T \geq a_u\) 吗,这样转换为啥是对的?

A1

对于经过 $u$ 的每个时刻,假设中间某个时刻捐了 $b_u$ 块钱,那么前面的时刻肯定都有 $T \geq a_u - b_u + b_u$。我们把这个捐钱时刻移到最后,那么后面每次进入 $u$ 的时刻,$T$ 都多了本来要捐的 $b_u$,因此有 $T \geq a_u$,满足题目限制,且一定更优。

因此,我们将进入某个点时的限制转化成了在某个点时的限制。因此我们设 \(c_i = a_i - b_i\)

每个点都会在行走捐钱的过程中突然变得不能到达。假设点 \(u\) 第一个不能到达,那么 \(u\) 会分裂成若干连通块,我们就要保证这时候除了人在的连通块之外所有点都被捐钱了。

我们将点的消失转化成边的消失。如果一条边中的一个点消失了,这条边就不能经过了。因此,我们给边 \((u, v)\) 加一个边权 \(w = \max(c_u, c_v)\),表示其中这两个点先消失的那个点的时间。

由于边是按照 \(w\) 从大到小消失的,因此这启发我们建 Kruskal 重构树。我们建出来这棵树之后,假设当前我们在 \(u\) 的子数上,那么 \(a_u\) 就是这个点代表的边的消失时间。

考虑 DP。设 \(f_u\) 表示我们在重构树上以 \(u\) 为根的子树在原图中代表的连通块,这个人对每个点捐完钱所需要的最小初始钱财。设 \(s_u\) 表示重构树上以 \(u\) 为根的子树中 \(b_i\) 之和。

建出重构树后,我们有一个很关键的性质:\(u\) 这个点一定是整个连通块中最先消失的。因此,我们要保证在捐完一颗子树的所有钱后,还能经过 \(u\) 到另一颗子树。

我们假设要先进入子树 \(v'\),捐完这个子树的钱后经过 \(u\) 到达另一颗子树。容易发现,由于之后我们还要有实力经过 \(u\),所以在 \(v'\) 子树中随便乱走都不会出现断边。假设 \(u\) 这个边经过的限制是 \(w\)

我们设初始的钱数为 \(T\),那么就要有如下式子:

  • 捐完 \(v'\) 的钱后要能经过 \(u\) 这条边:\(T - s_{v'} \geq w\)
  • 捐完 \(v'\) 的钱后要能捐完 \(v\) 子树:\(T - s_{v'} \geq f_v\)

因此,\(T \geq s_{v'} + \max(w, f_v)\),因此 \(f_u = s_{v'} + \max(w, f_v) = s_u - s_v + \max(w, f_v)\)

posted @ 2025-12-07 09:53  DE_aemmprty  阅读(13)  评论(1)    收藏  举报