spfa,分层图,340. 通信线路,《算法竞赛进阶指南》

340. 通信线路 - AcWing题库

在郊区有 N 座通信基站,P 条 双向 电缆,第 i 条电缆连接基站 Ai 和 Bi。

特别地,1 号基站是通信公司的总站,N 号基站位于一座农场中。

现在,农场主希望对通信线路进行升级,其中升级第 i 条电缆需要花费 Li。

电话公司正在举行优惠活动。

农产主可以指定一条从 1 号基站到 N 号基站的路径,并指定路径上不超过 K 条电缆,由电话公司免费提供升级服务。

农场主只需要支付在该路径上剩余的电缆中,升级价格最贵的那条电缆的花费即可。

求至少用多少钱可以完成升级。

输入格式

第 11 行:三个整数 N,P,K。

第 2..P+12.. 行:第 i+1 行包含三个整数 Ai,Bi,Li。

输出格式

包含一个整数表示最少花费。

若 11 号基站与 N 号基站之间不存在路径,则输出 −1。

数据范围

0≤K<N≤1000,
1≤P≤10000
1≤Li≤1000000

输入样例:
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例:
4

 解析参考至:AcWing 340. 通信线路 - AcWing这道题用二分也可以二分,Dijkstra,340. 通信线路_Landing_on_Mars的博客-CSDN博客

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 1000 + 5;
int n, p, k;
vector<pair<int, int>>G[N];
int dist[N][N], vis[N];

void spfa() {
	memset(dist, 0x3f3f3f3f, sizeof(dist));
	int t;
	queue<int>q;
	q.push(1);
	dist[0][1]=0;
	while (!q.empty()) {
		t = q.front();
		q.pop();
		vis[t] = 0;
		for (int i = 0; i < G[t].size(); i++) {
			int j = G[t][i].first, w = max(G[t][i].second,dist[0][t]);
			if (dist[0][j] > w) {
				dist[0][j] = w;
				if (vis[j] == 0) {
					q.push(j);
					vis[j] = 1;
				}
			}
			for (int r = 1; r <= k; r++) {
				w = min(dist[r-1][t], max(G[t][i].second, dist[r][t]));
				if (dist[r][j] > w) {
					dist[r][j] = w;
					if (vis[j]==0) {
						q.push(j);
						vis[i] = 1;
					}
				}
			}
		}
	}
}

int main() {
	cin >> n >> p >> k;
	for (int i = 1,a,b,t; i <= p; i++) {
		scanf("%d%d%d", &a, &b, &t);
		G[a].push_back({ b,t });
		G[b].push_back({ a,t });
	}
	spfa();
	int ans = 1e9;
	for (int i = 0; i <= k; i++) {
		ans = min(ans, dist[i][n]);
	}
	if (ans == 1e9)
		cout << -1 << endl;
	else
		cout << ans << endl;
	return 0;
}

posted @ 2023-09-02 21:20  Landnig_on_Mars  阅读(12)  评论(0编辑  收藏  举报  来源