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;
}

posted on 2025-04-10 17:35  itdef  阅读(6)  评论(0)    收藏  举报

导航