• L2-001 紧急救援


      附上题目链接:https://www.patest.cn/contests/gplt/L2-001

      

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

    输入格式:

    输入第一行给出4个正整数N、M、S、D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

    输出格式:

    第一行输出不同的最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出首尾不能有多余空格。

    分析: 这个就是在dijkstra上加了一维, 我们改一下dijkstra算法即可。 附上代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int maxn = 500 + 50;
    int N, M, S, D;
    struct edge { int to, cost; };
    vector<edge> G[maxn];
    int node_weight[maxn];
    
    struct Dij {
        int u;
        int dis, peo_num;
        bool operator< (const Dij &r) const {
            if(dis == r.dis) {
                return peo_num < r.peo_num;
            }else return dis > r.dis;
        }
    };
    
    bool vis[maxn];
    int dist[maxn], peonum[maxn];
    int pre[maxn];
    int routenum[maxn];
    void dijkstra(int u) {
        for(int i=0; i<N; i++) {
            vis[i] = 0;
            dist[i] = inf;
            peonum[i] = -inf;
            routenum[i] = 0;
        }
        priority_queue<Dij> que;
        pre[u] = -1; routenum[u] = 1;
        dist[u] = 0; peonum[u] = node_weight[u];
        que.push((Dij){u, dist[u], peonum[u]});
        while(!que.empty()) {
            Dij tp = que.top(); que.pop();
            if(vis[tp.u]) continue;
            vis[tp.u] = 1;
            for(int i=0; i<G[tp.u].size(); i++) {
                edge e = G[tp.u][i];
    
                if(dist[e.to] > dist[tp.u] + e.cost) routenum[e.to] = routenum[tp.u];
                if(dist[e.to] == dist[tp.u] + e.cost) routenum[e.to] += routenum[tp.u];
    
                if(dist[e.to] > dist[tp.u] + e.cost ||
                    (dist[e.to] == dist[tp.u] + e.cost && peonum[e.to] < peonum[tp.u] + node_weight[e.to])) {
                        dist[e.to] = dist[tp.u] + e.cost;
                        peonum[e.to] = peonum[tp.u] + node_weight[e.to];
                        que.push((Dij){e.to, dist[e.to], peonum[e.to]});
                        pre[e.to] = tp.u;
                    }
            }
        }
    }
    
    int main() {
        scanf("%d%d%d%d", &N, &M, &S, &D);
        for(int i=0; i<N; i++) scanf("%d", &node_weight[i]);
        for(int i=0; i<M; i++) {
           int u, v, c;
           scanf("%d%d%d", &u, &v, &c);
           G[u].push_back((edge){v, c});
           G[v].push_back((edge){u, c});
        }
        dijkstra(S);
        vector<int> route;
        printf("%d %d
    ", routenum[D], peonum[D]);
        int now = D;
        route.push_back(now);
        while(pre[now] != -1) {
            now = pre[now];
            route.push_back(now);
        }
        for(int i=route.size()-1; i>=0; i--) {
            printf("%d%c", route[i], i==0?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    Java硬件同步机制Swap指令模拟+记录型信号量模拟
    算法(第四版)练习 1.1.26 ~ 1.1.31
    C++ 电路布线/最短路径问题
    线性代数笔记
    算法导论(第三版)练习 2.2-1 ~ 2.2-4
    条款45: 弄清C++在幕后为你所写、所调用的函数
    条款42: 明智地使用私有继承
    条款41: 区分继承和模板
    【python】字符遍历
    【python】range的用法
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5554736.html
Copyright © 2020-2023  润新知