L2-001 紧急救援

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int g[510][510];
int num[510];
int dist[510];
int st[510];
//st确定的顺序不一定是最短路径的顺序,二者没关系
int value[510];//到每个点最短路救援队伍的数量
int cnt[510];//到每个点最短路的数目
int pre[510];//父节点
int main() {
    int n, m, s, d;
    cin >> n >> m >> s >> d;
    memset(dist, 0x3f, sizeof dist);
    memset(g, 0x3f, sizeof g);
    memset(pre, -1, sizeof pre);
    for (int i = 0; i < n; i++) {
        cin >> num[i];
    }
    for (int i = 0; i < m; i++) {
        int c1, c2, w;
        cin >> c1 >> c2 >> w;
        g[c1][c2] = w;
        g[c2][c1] = w;

    }

    dist[s] = 0;
    int t = -1;
    value[s] = num[s];
    cnt[s] = 1;
    //     st[s] = 1;

    for (int j = 0; j < n; j++) {
        int tmp = 0;
        t = -1;
        for (int i = 0; i < n; i++) {
            if (!st[i] && (t == -1 || dist[i] < t)) {
                t = dist[i];
                tmp = i;
            }
        }

        st[tmp] = 1;
        for (int i = 0; i < n; i++) {
            if (dist[i] > dist[tmp] + g[tmp][i]) {//如果有更短路径
                dist[i] = dist[tmp] + g[tmp][i];
                value[i] = value[tmp] + num[i];
                pre[i] = tmp;
                cnt[i] = cnt[tmp];
            }

            else if ((dist[i] == dist[tmp] + g[tmp][i]) && (tmp != i)) {//如果与最短路长度相等
                cnt[i] += cnt[tmp];
                if (value[i] < value[tmp] + num[i]) {
                    value[i] = value[tmp] + num[i];
                    pre[i] = tmp;
                }
            }

        }
    }

    cout << cnt[d] << ' ' << value[d] << endl;
    vector<int> path;
    path.push_back(d);
    while (pre[d] != -1) {
        path.push_back(pre[d]);
        d = pre[d];
    }
    reverse(path.begin(), path.end());
    for (auto iter = path.begin(); iter != path.end() - 1; iter++)
        cout << *iter << ' ';
    cout << path.back();

}

/*本题出现的问题
    1.数组初始化,g[][]起初没有初始化,应该初始化两点距离距离为正无穷
    2.无向图要存两个方向的边
    3.cnt[i] += cnt[tmp]; 思路要明晰,不是加一是把到tmp的最短路数都加上
    4.if elseif 使用时一定注意第二个用if 还是 else if
    5.总体逻辑要理清,模板题
*/

 

posted @ 2023-03-16 20:17  youngbrooke  阅读(124)  评论(0)    收藏  举报