题目
编号为1到N的N个城市间有M条铁路,通过每条铁路花费时间T_i,为了减少从城市1到N的时间,现在决定将其中一条铁路改建成高铁,改建后通过该条铁路的时间将减半(向下取整数),求改建哪条铁路可以使得改建后从城市1到城市N的时间最短
输入:第一行N和M
接下来M行,每行A_i, B_i, T_i分别是第i条铁路的起点和终点,以及时间
输出:改建的铁路编号以及改建后从1到N的时间
注意:铁路是双向的,保证解唯一
80%数据N,M<5000,100%数据N,M<1000000
--------------------------------------------------------------------------------
思路
从节点1和节点n分别做一次Dijkstra求从节点1出发的到每个点的最短路(保存在d1里)和从节点n出发到每个点的最短路(保存在d2里)。然后遍历m条边,建高铁后从节点1到节点n的最短路为min(d1[u] + d2[v] + len[u,v])
经tydety97指正,d1[u]的路径有可能包含边(u,v),d2[v]的路径也有可能包含边(u,v),因此最短路的表达式应作
min(min(d1[u] + d2[v], d1[v] + d2[u]) + len[u,v])
数据规模显示是稀疏图,因此用堆优化的Dijkstra,相应的采用邻接表的数据结构(本来邻接矩阵就会爆内存——vs显示数组过大)存储路网信息,复杂度为O(mlogn + m) = O(mlogn)
--------------------------------------------------------------------------------
代码
主程序
// 用堆优化的Dijkstra算法算两遍,分别从源点和汇点开始算,
// 算得d1数组记录所有点到源点的距离,d2数组记录所有点到汇点的距离
// 遍历m条边,ans = min(min(d1[u] + d2[v], d1[v] + d2[u]) + len[u,v])
#include<cstdio>
#include<queue>
#include<vect