B. Fake Plastic Trees

什么时候才能会做贪心题啊 😢。

首先给出几个 observation:

  • 以点 \(u\) 为链底进行操作,给 \(u\) 设置的增量一定是在使 \(u\) 的权值不超过 \(r_u\) 的情况下最大的值;
  • \(u\) 的所有子树均取最优操作数时,\(u\) 也总是取最优操作数。这是因为若存在子树没取最优操作数,一定至少多了一次操作,但是多的这一次操作显然不如直接在 \(u\) 上操作优。

基于此可以设计一个 \(\rm dfs\),往回传最优操作数条件下的最大增量,若小于 \(l_u\),就再新增一次操作,将值提到 \(r_u\).

C. Keshi in Search of AmShZ

感觉这题还是蛮妙的?突然发现自己没学懂 \(\rm dijkstra\) /jk.

首先容易产生一个想法:只保留从 \(1\)\(n\) 最短路上的边,其它的边都 \(\rm block\) 掉。这个想法的 motivation 在于 \(\rm block\) 边的花费只有 \(1\),同时非最短路一定比最短路 至少多 \(1\).

然而这个策略是有问题的。考虑某个点 \(u\) 有两个后继 \(v,w\),若 \(v\) 是从 \(1\)\(n\) 最短路上的点,\(w\) 不是,按照上文的策略应该 \(\rm block\)\(w\) 的边。然而如果 \(v\) 有很多非最短路上的后继咋办?这时我们应该进行权衡,说不定直接 \(\rm block\)\(v\) 反而会更优。

基于此设计一个类 \(\rm dijkstra\) 的算法:记 \(d_i\) 为从 \(i\)\(n\) 最坏情况的最小花费,同时连上反向边,记 \(\text{deg}_i\) 为点 \(i\) 反向边的入度。从 \(n\) 开始跑 \(\rm dijkstra\),对于反向边 \((v,u)\),若 \(d_v+\text{deg}_u<d_u\),则更新 \(d_u\),同时将 \(u\) 的入度减一。最后答案就是 \(d_1\).

考虑到在 \(\rm dijkstra\) 的过程中,从队列中取出点 的距离标记一定是不降的。那么对点 \(u\) 而言,若将它的后继按 \(d\) 从小到大排序(也即从队列中取出点的顺序),想要取到第 \(i\) 个后继对应的 \(d\),就必须把排在第 \(i\) 个之后的后继全都 \(\rm block\)[1],同时还有 \(1\) 的边权,所以边权为当前 \(\text{deg}_u\).


  1. 这里其实不太严谨,不过当 \(d\) 相同的时候取排在最后面的那一个肯定是最优的。 ↩︎

posted on 2020-06-18 16:10  Oxide  阅读(123)  评论(0编辑  收藏  举报