1003 Emergency (25 分)(最短路Dijkstra)

本文介绍了一个紧急救援问题,利用Dijkstra算法求解从起点城市到目标城市的最短路径,并在此过程中最大化救援队伍的集结。通过实例代码展示了如何结合城市救援队伍数量和道路长度,计算不同最短路径的数量和最大集结队伍数。
摘要由CSDN通过智能技术生成

 题目链接:

题目详情 - L2-036 网红点打卡攻略 (25 分) (pintia.cn)https://pintia.cn/problem-sets/994805046380707840/problems/1336215880692482059

题目表述: 

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input Specification:

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C1​ and C2​ - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1​, c2​ and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1​ to C2​.

Output Specification:

For each test case, print in one line two numbers: the number of different shortest paths between C1​ and C2​, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input:

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:

2 4

思路:

1. 最短路Dijkstra, 求最短路条件下的最大点权。

2. 就是给出一个无向图的边权和点权,判断从c1到c2的最短路径,以及在最短路径的前提下找出最大点权。

3. 用Dijkstra先求最短路,求最短路过程中同时求出最大点权

代码: 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 505, inf = 0x3f3f3f3f;

//G为邻接矩阵,w点权,即每个城市的队伍, maxT最多能聚集的队伍, d到目的城市的最短距离, num最短路数量
int G[maxn][maxn], w[maxn], maxT[maxn], d[maxn], num[maxn];
int n, m, c1, c2;
bool vis[maxn]; //判断是否访问过该城市

void Dijkstra(int s){
	fill(d, d+maxn, inf); //初始化最短距离
	d[s] = 0; //到自身的最短距离为0
	maxT[s] = w[s]; //初始队伍数为自己的点权
	num[s] = 1; //初始最短路只有1条
	for(int i = 0; i < n; i++){ //遍历n个城市
		int MIN = inf, u = -1;
		for(int j = 0; j < n; j++){ // 查找未访问过的城市中距离最小的
			if(!vis[j] && d[j] < MIN){
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return; // 未找到直接返回
		vis[u] = true; // 标记当前访问的城市
		for(int j = 0; j < n; j++){
			if(!vis[j] && G[u][j]){ // 查找能直接到达的未访问过的城市
				if(d[u] + G[u][j] < d[j]){ //如果从u到v的最短距离可以优化
                    // 更新距离和最大权值, 最短路条数不变
					d[j] = d[u] +G[u][j]; 
					maxT[j] = maxT[u] + w[j];
					num[j] = num[u];
				}else if(d[u] + G[u][j] == d[j]){ //最短路不唯一
                    // 如果找到相同的最短距离,最短路条数累加
					if(maxT[u] + w[j] > maxT[j]){ // 如果总权值更大,则更新最大权值
						maxT[j] = maxT[u] + w[j];
					}
					num[j] += num[u];
				}
			}
		}
	}
}

int main(){
	cin >> n >> m >> c1 >> c2;
	for(int i = 0; i < n; i++){
		cin >> w[i];
	}
	for(int i = 0; i < m; i++){
		int a, b, c;
		cin >> a >> b >> c;
		G[a][b] = G[b][a] = c;
	}
	Dijkstra(c1);
	printf("%d %d",num[c2], maxT[c2]); // 输出
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值