1003 Emergency (25 分)

1003 Emergency (25 分)(dijkstra算法)

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

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

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

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

输入格式

第一行包含四个整数 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 的救援队数量。

接下来 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 2N500,
1 ≤ M ≤ 600 1≤M≤600 1M600,
1 ≤ L i ≤ 200 1≤Li≤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

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值