POJ_3255_次短路问题
题目大意:Bessie在农场里过上了安逸的日子。她现在每天都去找她的一个好朋友去扯一下POJ上面的题怎么做,Pascal和C到底更好用等问题。可是她不愿意走最短路,因为她想欣赏沿途的风景什么的。现在给出农场数N和道路数R,在后面的R行中给出起点和终点以及道路长度。请帮助Bessie算出来次短路的长度。所谓次短路,就是指严格比最短路(可能不止一条)短,但是不长于其他任何路径的路径。数据中一定存在至少一条次短路。
本人在POJ上做过次小生成树的问题。当时的解决思路是把最小生成树里面的边逐个去掉,而计算现在的最小生成树。证明很简单,在此略去。可是现在解决次短路问题也采用这样的思路就会非常麻烦。SPFA一次的时间复杂度大约是O(2n),枚举最短路的边是O(r)级别的,这样看来最坏情况下的时间复杂度就会有O(2nr),将近10亿。就算是O(r)太过悲观的话,想在2秒内出解也比较悬。
分析一下状况,次短路不可能与最短路完全重合,那么就一定会有一段比较绕路。绕路的地方不可能超过两处,那样就有一条路短于这条路而长于最短路,矛盾。因此可以对所有的边加以枚举。首先用Dijkstra或SPFA以原点和终点为源分别做一次单源最短路,并把答案存在dist_0和dist_n两个数组中。那么,对于任何一条边(i, j),下面的二者之一就有可能是次短路的长:
dist_0[i] + len(i, j) + dist_n[j] 和 dist_0[j] + len(i, j) + dist_n[i]
注意,如果其中一个的长度等于最短路的长度(即dist_n[0]),就一定不能选,因为这违反次短路的定义。两个都要枚举,因为可能有其中一个等于最短路的长,如果只取较小的值另外一个就废掉了。由此可以写出以下代码: