题解:AT_abc137_e [ABC137E] Coins Respawn

· · 题解

我发现我的思路和这位同志的这篇文章一样,但是这位同志有些地方讲得不大明白,我再来补充一下。说明:此篇文章引用其他文章作者思路,已征得原作者同意,在此表示感谢。

首先,正如这位同志所说:因为要最终减去 T\times P 个硬币,所以不妨把每条边减去 P,就完美地解决了这个问题。随后要求出到 n 点能最多获得几个硬币,且每条边可以重复走,这不难想出用最长路的方法做,因为有可能获得的硬币数量无上限(即出现正环),所以还需要判正环,因此可以使用 SFPA 实现。我们还需注意到的是如样例三这样的图:

如果只按照上面的做法做,会在 2 号点上浪费太多时间,因为 2 号点上有环,而且 SPFA 算法还会告诉你图中有正环,硬币数量无上限,但是我们可以看到事实并非这样,事实是虽然 2 号点有正环,但一进入 2 号点,也回不来了,无法返回去 n 号点(即 4 号点)的正道了,所以 2 号点的正环其实对答案没有影响。因此,我们不妨建一个反图,从终点 n 出发,使用 DFS 寻找从终点出发能到的点。这样,在 SPFA 时就可以忽略掉从终点 n 出发到不了的点,节省了时间,排除了对答案不影响的正环的干扰,可谓一举两得。

现在我们就可以设计出解决此题的算法:

  1. 输入。
  2. 使用 DFS 查找从终点出发可以到的点。(注意判重,别对查找过的点重新查找,陷入死循环)时间复杂度:O(N+M)
  3. SPFA 求最长路。(注意判正环,忽略从终点 n 出发到不了的点)时间复杂度:O(N\times M)
  4. 输出。(如果有在有限范围内的解,且该解小于 0,记得把答案换成 0,因为最多也就把硬币扣光而已)

我们可以看到:核心算法时间复杂度为:O(N+M+N\times M),我们再看:题目中说 2\leq N\leq 25001\leq M\leq 5000,所以 N+M+N\times M 最大情况下约是是 1.25\times 10^7,而时间限制是 2.00s,足以通过此题。

AC Code

可参考文章开头想补充的题解的代码。要说明的是,代码中不必像这位同志一样开 long long,开 int 就够了。