【题解】【AcWing】1475. 紧急情况

AcWing 专栏收录该内容
170 篇文章 0 订阅

1475. 紧急情况

原题传送:AcWing 1475. 紧急情况

作为城市的紧急救援团队负责人,你将获得一张你所在国家的特殊地图。

该地图显示了一些通过道路连接的分散城市,道路是双向的

地图上标出了每个城市的救援队数量以及每对城市之间的每条道路的长度。

当其他城市发出紧急求援信息时,你的工作是尽快带领你的士兵前往该地点,同时,在途中尽可能多地调动救援帮手。

输入格式

第一行包含四个整数 N N N ,表示城市数量(城市编号从 0 0 0 N − 1 N-1 N1 ), M M M 表示道路数量, C 1 C_1 C1 表示你当前所在的城市编号, C 2 C_2 C2 表示发出紧急求援信息的城市编号。

第二行包含 N N N 个整数,其中第 i i i 个整数表示城市 i i i 的救援队数量。

接下来 M M M 行,每行包含三个整数 c 1 , c 2 , L i c_1,c_2,L_i c1,c2,Li ,表示城市 c 1 c_1 c1 和城市 c 2 c_2 c2 之间存在一条道路相连,道路长度为 L i L_i Li

数据保证 C 1 C_1 C1 C 2 C_2 C2 之间至少存在一条路径相连。

输出格式

共一行,两个整数,第一个整数表示 C 1 C_1 C1 C 2 C_2 C2 之间最短路的数量,第二个整数表示走最短路的情况下,能聚集到的救援队最大数量。

数据范围

2 ≤ N ≤ 500 2 \le N \le 500 2N500 ,
1 ≤ M ≤ 600 1 \le M \le 600 1M600 ,
1 ≤ L i ≤ 200 1 \le L_i \le 200 1Li200 ,
每个城市包含的救援人员数量不超过 200 200 200

输入样例:

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

输出样例:

2 4

思路:

dijkstra算法,在更新时分不等和等于两种情况记录最短路径的条数和顶点的最大权值。

题解:

#include <bits/stdc++.h>

using namespace std;

const int N = 510;

int n, m, S, T;
int w[N], d[N][N];
int dist[N], cnt[N], sum[N];
bool st[N];

void dijkstra()
{
	memset(dist, 0x3f, sizeof dist);
	dist[S] = 0, cnt[S] = 1, sum[S] = w[S];
	
	for(int i = 0; i < n; i++)
	{
		int t = -1;
		for(int j = 0; j < n; j++)
			if(!st[j] && (t == -1 || dist[t] > dist[j]))
				t = j;
		st[t] = true;
		
		for(int j = 0; j < n; j++)
		{
			if(dist[j] > dist[t] + d[t][j])
			{
				dist[j] = dist[t] + d[t][j];
				cnt[j] = cnt[t];
				sum[j] = sum[t] + w[j]; 
			}
			else if(dist[j] == dist[t] + d[t][j])
			{
				cnt[j] += cnt[t];
				sum[j] = max(sum[j], sum[t] + w[j]);
			}
		}
	}
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &S, &T);
	
	for(int i = 0; i < n; i++)
		scanf("%d", &w[i]);
	
	memset(d, 0x3f, sizeof d);
	while(m--)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		d[a][b] = d[b][a] = min(d[a][b], c);
	}
	
	dijkstra();
	
	printf("%d %d", cnt[T], sum[T]);

    	return 0;
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值