1003 Emergency (25 分)(dijkstra算法)
作为城市的紧急救援团队负责人,你将获得一张你所在国家的特殊地图。
该地图显示了一些通过道路连接的分散城市,道路是双向的。
地图上标出了每个城市的救援队数量以及每对城市之间的每条道路的长度。
当其他城市发出紧急求援信息时,你的工作是尽快带领你的士兵前往该地点,同时,在途中尽可能多地调动救援帮手。
输入格式
第一行包含四个整数 N N N,表示城市数量(城市编号从 0 0 0 到 N − 1 N−1 N−1), M M M 表示道路数量, C 1 C_1 C1 表示你当前所在的城市编号, C 2 C_2 C2 表示发出紧急求援信息的城市编号。
第二行包含 N N N 个整数,其中第 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 C1 C1 和 C 2 C2 C2 之间至少存在一条路径相连。
输出格式
共一行,两个整数,第一个整数表示 C 1 C1 C1 和 C 2 C2 C2 之间最短路的数量,第二个整数表示走最短路的情况下,能聚集到的救援队最大数量。
数据范围
2
≤
N
≤
500
2≤N≤500
2≤N≤500,
1
≤
M
≤
600
1≤M≤600
1≤M≤600,
1
≤
L
i
≤
200
1≤Li≤200
1≤Li≤200,
每个城市包含的救援人员数量不超过
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
#include <iostream>
#include <cstring>
#include <algorithm>
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()
{
cin >> n >> m >> S >> T;
for (int i = 0; i < n; i ++ ) cin >> w[i];
memset(d, 0x3f, sizeof d);
while (m -- )
{
int a, b, c;
cin >> a >> b >> c;
d[a][b] = d[b][a] = min(d[a][b], c);
}
dijkstra();
cout << cnt[T] << ' ' << sum[T] << endl;
return 0;
}