Roadblocks 最短路计数
// Roadblocks 最短路计数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
https://loj.ac/p/10076
原题来自:USACO 2006 Nov. Gold
贝茜把家搬到了一个小农场,但她常常回到 FJ 的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,
于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。
贝茜所在的乡村有 R(1 <= R <= 10^5) 条双向道路,每条路都连接了所有的 N(1 <= N <= 5000) 个农场中的某两个。
贝茜居住在农场 1,她的朋友们居住在农场 N(即贝茜每次旅行的目的地)。
贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且一条路可以重复走多次。
当然第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。
一句话题意:给一张无向图,求这张图的严格次短路之长。
输入格式
输入文件的第 1 行为两个整数,N 和 R,用空格隔开;
第 2 ~~ R+1 行:每行包含三个用空格隔开的整数 A、B 和 D,表示存在一条长度为 D(1 <= D <= 5000) 的路连接农场 A 和农场 B。
输出格式
输出仅一个整数,表示从农场 1 到农场 N 的第二短路的长度。
输入
4 4
1 2 100
2 4 200
2 3 250
3 4 100
输出
450
4 5
1 2 100
2 4 200
2 3 100
3 4 100
1 4 301
301
最短路:1 -> 2 -> 4(长度为 100+200=300) 第二短路:1 -> 2 -> 3 -> 4(长度为 100+250+100=450)
*/
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int M = 2e5 + 10;
const int N = 5010;
int h[N], e[M], ne[M],w[M], idx;
int n, m;
int dist[N][2]; // 存储所有点到1号点的距离
bool st[N][2]; // 存储每个点的最短距离是否已确定
struct ELE {
int id, type, dist;
// 重载 > 运算符,用于优先队列的greater比较
bool operator > (const ELE& t) const {
return dist > t.dist; // 按距离从小到大排序
}
};
void add(int a, int b, int l) {
e[idx] = b,w[idx]=l, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra() {
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
dist[1][0] = 0;
priority_queue<ELE, vector<ELE>, greater<ELE>> heap;
heap.push({ 1,0, 0 }); // first存储距离,second存储节点编号
while (!heap.empty()) {
ELE t = heap.top();heap.pop();
int id = t.id; int type = t.type; int distance = t.dist;
if (st[id][type] == true) continue;
st[id][type] = true;
for (int i = h[id]; i != -1; i = ne[i]) {
int j = e[i]; int d = w[i];
if (j == 4) {
int deg = 9;
}
if (dist[j][0] > d + distance) {
dist[j][1] = dist[j][0];
dist[j][0] = d + distance;
heap.push({j,0,dist[j][0]});
heap.push({ j,1,dist[j][1] });
}
else if (dist[j][1] > d + distance && d + distance > dist[j][0]) {
dist[j][1] = d + distance;
heap.push({ j,1,dist[j][1] });
}
}
}
if (dist[n][1] > 0x3f3f3f3f / 2) {
cout << -1 << endl;
}
else {
cout << dist[n][1] << endl;
}
return;
}
int main()
{
memset(h, -1, sizeof h);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int a, b, l; cin >> a >> b >> l;
add(a, b, l); add(b, a, l);
}
dijkstra();
return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力

