#P16930. SGU 314 — K 短路(Shortest Paths)
SGU 314 — K 短路(Shortest Paths)
难度估计:CF 3100~3300
题目描述
给定一个带正权的有向图,其中一个顶点为源点 ,另一个顶点为终点 。
先求从 到 的最短路径,然后求第二短路径,即除第一条路径之外最短的一条;再求第三短路径,以此类推。请输出前 条路径的长度。
这里的“路径”允许重复经过顶点或边,因此实际上求的是前 短的 walk。不同路径可以具有相同的长度。
输入格式
第一行包含三个整数 :
- ;
- ;
- 。
第二行包含两个整数 ,满足 且 。
接下来 行,每行包含三个整数 ,表示一条从 到 、长度为 的有向边:
- ,;
- 。
同一对顶点之间可以存在多条平行边。
输出格式
输出 行,按非降序给出前 条从 到 的路径长度。
如果实际存在的路径数量不足 条,则对每一条不存在的路径输出:
NO
样例 1
4 5 5
1 4
1 2 1
2 3 1
3 4 1
1 3 1
2 4 1
2
2
3
NO
NO
样例 2
4 4 5
1 4
1 2 10
2 3 10
3 4 10
3 2 10
30
50
70
90
110
样例 3
2 2 10
1 2
1 2 5
2 1 7
5
17
29
41
53
65
77
89
101
113
算法要点
使用 Eppstein 的 短路算法。
先在反图上从 做 Dijkstra,得到每个点到 的最短距离 ,并选出一棵指向 的最短路树。对于任意非树边 ,定义其偏离代价:
。
一条 路径可以表示为“最短路树路径 + 若干条 sidetrack 边”,其长度等于 加上所有 sidetrack 的 之和。
对每个顶点维护从该点沿最短路树到 的路径上可以选择的 sidetrack,并用可持久化可合并堆组织。随后使用全局优先队列按照附加代价从小到大枚举候选状态,即可依次得到前 短路径。
复杂度约为 。