当前位置: 首页 > news >正文

天梯赛:L2-001 紧急救援

题目

L2-001 紧急救援

题目描述

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

输入格式

输入第一行给出 4 4 4 个正整数 N 、 M 、 S 、 D N、M、S、D NMSD,其中 N N N 2 ≤ N ≤ 500 2≤N≤500 2N500)是城市的个数,顺便假设城市的编号为 0 0 0 ~ ( N − 1 ) (N−1) (N1) M M M 是快速道路的条数; S S S 是出发地的城市编号; D D D 是目的地的城市编号。

第二行给出 N N N 个正整数,其中第 i i i 个数是第 i i i 个城市的救援队的数目,数字间以空格分隔。随后的 M M M 行中,每行给出一条快速道路的信息,分别是:城市 1 1 1、城市 2 2 2、快速道路的长度,中间用空格分开,数字均为整数且不超过 500 500 500。输入保证救援可行且最优解唯一。

输出格式

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

输入样例

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例

2 60
0 1 3

解题思路

这道题目是一个典型的最短路径问题,但不仅仅是求最短路径,还需要考虑在最短路径的基础上,统计最短路径的数目以及尽可能多地召集救援队。因此,我们需要在Dijkstra算法的基础上进行一些扩展。

Dijkstra算法回顾

Dijkstra算法是一种用于求解单源最短路径的经典算法。它的基本思想是从起点开始,逐步扩展到其他节点,每次选择当前距离起点最近的节点,并更新其邻居节点的距离。

本题的扩展

在本题中,我们不仅需要找到最短路径,还需要:

  1. 统计最短路径的条数:即从起点到终点的最短路径有多少条。
  2. 在最短路径的基础上,选择救援队数量最多的路径:即在多条最短路径中,选择救援队数量最多的那条。

为了实现这些功能,我们需要在Dijkstra算法的基础上增加一些额外的信息:

  • cnt[i]:表示从起点到城市i的最短路径条数。
  • nums[i]:表示从起点到城市i的最短路径上能够召集的救援队数量。
  • pre[i]:表示在最短路径中,城市i的前驱节点,用于最后输出路径。

代码实现

#include<bits/stdc++.h>
using namespace std;

void solve() {
    int n, m, s, d;
    cin >> n >> m >> s >> d;
    
    // 每个城市的救援队数量
    vector<int> w(n);
    for (int i = 0; i < n; ++i)
        cin >> w[i];
    
    // 图的邻接矩阵表示,初始化为无穷大
    vector<vector<int>> g(n, vector<int>(n, 0x3f3f3f3f));
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        g[a][b] = g[b][a] = c;  // 无向图
    }
    
    // Dijkstra算法的初始化
    vector<int> vis(n, 0);  // 标记是否访问过
    vector<int> cnt(n, 0);  // 最短路径条数
    vector<int> nums(n, 0); // 救援队数量
    vector<int> dist(n, 0x3f3f3f3f);  // 最短距离
    vector<int> pre(n, -1);  // 前驱节点
    
    dist[s] = 0;  // 起点到自己的距离为0
    cnt[s] = 1;   // 起点到自己的最短路径条数为1
    nums[s] = w[s];  // 起点到自己的救援队数量为w[s]
    
    // Dijkstra算法主循环
    for (int i = 0; i < n; ++i) {
        int x = -1;
        // 找到当前未访问的节点中距离起点最近的节点
        for (int j = 0; j < n; ++j) {
            if (!vis[j] && (x == -1 || dist[x] > dist[j]))
                x = j;
        }
        if (x == -1) break;  // 所有节点都已访问
        vis[x] = 1;  // 标记为已访问
        
        // 更新邻居节点的距离
        for (int j = 0; j < n; ++j) {
            if (dist[j] > dist[x] + g[x][j]) {
                dist[j] = dist[x] + g[x][j];
                cnt[j] = cnt[x];  // 有更优的最短路径,直接更新最短路径条数
                nums[j] = nums[x] + w[j];  // 有更优的最短路径,直接更新救援队数量
                pre[j] = x;  // 更新前驱节点
            } else if (dist[j] == dist[x] + g[x][j]) {
                cnt[j] += cnt[x];  // 当前更新的距离和先前更新的最短路径距离一致,增加最短路径条数
                if (nums[j] < nums[x] + w[j]) {
                    nums[j] = nums[x] + w[j];  // 距离一致情况下,取最大救援队数量
                    pre[j] = x;  // 取最大救援队数量路径,同时更新前驱节点
                }
            }
        }
    }
    
    // 输出最短路径数目以及救援队数目最大的结果
    cout << cnt[d] << ' ' << nums[d] << '\n';
    
    // 输出路径
    vector<int> path{d};
    int idx = d;
    while (idx != s) {
        idx = pre[idx];
        path.push_back(idx);
    }
    
    // 逆序输出路径
    for (int i = path.size() - 1; i >= 0; i--)
        cout << path[i] << " \n"[i == 0];
}

int main() {
    cin.tie(nullptr), cout.tie(nullptr);
    ios::sync_with_stdio(false);
    solve();
    return 0;
}

相关文章:

  • 佛山 网站代写软文
  • 外贸一站式推广服务每日关键词搜索排行
  • 用.net做网站中含有论坛百度网站权重查询
  • 五金批发网站怎么做关键词优化资讯
  • 网站怎么做直播间网站建设在线建站
  • 自己做的网站为何手机不能浏览免费网站安全软件大全
  • 6.6.5 SQL访问控制
  • 第16届蓝桥杯模拟赛题解 第三场 Java
  • stm32使用(无线串口)实现收发、判断数据+DMA(HAL库)
  • 2022年全国职业院校技能大赛网络系统管理赛项模块A:网络构建(样题10)-网络部分解析-附详细代码
  • 跨端方案选型:对比Uni-app与Taro在复杂电商项目中的技术选型依据参考
  • 大白话解释负载均衡Nginx是什么 有什么用 怎么用#
  • ClkLog里程碑:荣获2024上海开源技术应用创新竞赛三等奖
  • 记录深度学习中有用的终端命令
  • 第三章 组件(11)- 动态组件与表格组件
  • 【Qt】MVC设计模式
  • Java线程池
  • LLVM - 编译器前端 - 将源文件转换为抽象语法树
  • 在docker容器中运行Ollama部署deepseek-r1大模型
  • C# String 常用操作方法详解
  • 检查SSH安全配置-sshd服务端未认证连接最大并发量配置
  • React Native 核心技术知识点快速入门
  • 用大白话解释日志处理Log4j 是什么 有什么用 怎么用
  • 45.matlab产生正弦叠加信号并保存为txt文本
  • 智能驾驶ai算法学习路线图
  • C# 使用 Newtonsoft.Json 序列化和反序列化对象实例