AOJ 1383 - Pizza Delivery
目录
题面
某座城市里有 个点和 条单向路径。从某一天开始连续的 天里,第 天会把第 条路径反向,同时在下一天会把这条路径的方向恢复成原方向。某人想从 点到 点,问在这 天里,第 天 点和 点间的最短路径相比原图是变长(输出 HAPPY)、变短(输出 SAD)还是不变(输出 SOSO)。
数据范围:
分析
首先我们可以考虑正向建一张图,同时反向建一张图。我们记原图为 ,记 代表 点到 点间的最短距离。
我们在正向图中以 为源点跑一遍单源最短路,即可得到 点到任一点 的最短路径 ;于此同时我们在反向图中以 为源点跑一遍单源最短路即可得到任一点 到 点的最短路 。
下面记当前我们反向的是边 ,反向后是 ,其长度为 。
何时变短?
若最短路变短,则在图 中所有从 点到 点的最短路一定经过 而一定不经过 。至于原因,最短路径上显然不可能出现环(即同时包含 和 ),而如果最短路径经过 的话,那么这条最短路也就是原图 中的最短路了,长度肯定不会发生变化。
在这种情况下,有 。若满足该条件,则最短路一定变短。反正,一定不变短。
何时变长?
经过上述是否变短的判断,到这一步时我们已经知道最短路不会变短了。
如果我们把 中所有最短路单独拿出来建一张图,我们将会得到一张 DAG 图 。
如果 中所有最短路都要经过 边,则 边必然是 中的桥。如果 边被反向了,那么最短路长度一定改变,即变长。
接下来就是如何判断 边是否为桥了。
记 代表 点到 点最短路的方案数,若有 则表明所有最短路一定经过 边,即 边为桥。
何时不变?
既不变长又不变短…… 当然就是不变啦(逃
实现
实现的时候我们不必要真的把最短路上所有边拿出来单独建图。我们可以通过判断 是否等于 来得知 边是否在 内。
统计最短路方案数可以随跑 Dijkstra 算最短路时同时完成(Dijkstra 本质就是个 DP,对吧)。需要注意的是,记录和判断最短路方案数的时候为了防止爆 long long 应当取模后比较。