L2-001 紧急救援(dijkstra算法练习)

news2024/11/19 22:42:00

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

输入格式:

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

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

输出格式:

第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到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

首先:最简单的就是无脑DFS搜索全部情况返回最优解 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 510;
int N, M, S, D, A, B, C, road = 0, love, mind = 1 << 20;//路径 救援数
vector<int>sove(maxn);
int MAP[maxn][maxn];
deque<int>ans;
deque<int>s;
bool vis[maxn][maxn];
void DFS(int str, int end, int d, int sum)//起始 结尾 路径 救援数
{
    if (str == end && mind >= d)
    { //达到目的地 
        if(mind > d)
        {
            road = 0;
            ans = s;
            mind = d;
            love = sum;
        }
        else if(d == mind && love < sum)
        {
            love = sum;
            ans = s;
        }
        road++;
        return;
    }
    else if(str == end)return;
    for (int i = 0; i < N; i++)
    {
        if (MAP[str][i] && !vis[str][i])
        {
            vis[str][i] = true;
            s.push_back(i);
            DFS(i, end, d + MAP[str][i], sum + sove[i]);
            vis[str][i] = false;
            s.pop_back();
        }
    }
}

int main()
{
    cin >> N >> M >> S >> D;
    for (int i = 0; i < N; i++)
    {
        cin >> sove[i];
    }
    for (int i = 0; i < M; i++)
    {
        cin >> A >> B >> C;
        MAP[A][B] = MAP[B][A] = C;
    }
    DFS(S, D, 0, sove[S]);
    cout << road << " " << love << endl << S;
    while (!ans.empty())
    {
        cout << " " << ans.front();
        ans.pop_front();
    }
    return 0;
}

但是缺陷也是比较明显的,如果图中各节点的联通网十分密集的话,那我们递归的深度就很容易导致系统栈被压爆,从而得不出答案

 那么就得涉及到最短路径算法了,常见的Dijkstra或者Floyd

当然也有Bellman 和 SPFA但是不怎么常使用到(主要是个人太菜,没做过那么多题)

简单的科普Dijkstra和Floyd算法

最短路径(Dijkstra算法和Floyd算法)_法苏ovo的博客-CSDN博客

基于Floyd大多是处理任意俩点最短路径(并且效率较低)而我们这题侧重于单源路径,就采用Dijikstra进行解题

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int maxn = 510;
int N, M, S, D, A, B, len;
vector<int>p(maxn), pre(maxn, -1), num(maxn), per(maxn), dis(maxn, INT_MAX);
// 各点的救援队数量  前置结点  从起点到该点的最短路数量 从起点到该点最短路的救援队数量 从起点到该点的最短距离 
bool vis[maxn];
struct edge
{
    int to, len;
    edge(int a, int b) : to(a), len(b) {};
};
vector<edge>e[maxn];
struct q_node
{
    int id, dis;
    q_node(int a, int b) :id(a), dis(b) {};
    bool operator< (const q_node& s)const
    {
        return dis > s.dis;
    }
};
void printf_path(int x)
{
    if (pre[x] == -1) return;
    printf_path(pre[x]);
    printf(" %d", x);
}
void dijkstra()
{
    dis[S] = 0, num[S] = 1, per[S] = p[S];
    priority_queue<q_node>Q;
    Q.emplace(S, dis[S]);
    while (!Q.empty())
    {
        auto x = Q.top();
        Q.pop();
        if (vis[x.id])continue;
        vis[x.id] = true;
        for (int i = 0; i < e[x.id].size(); i++)
        {
            auto y = e[x.id][i];//枚举邻居
            if (dis[y.to] == dis[x.id] + y.len)num[y.to] += num[x.id];
            if (dis[y.to] > dis[x.id] + y.len)num[y.to] = num[x.id];
            if ((dis[y.to] == dis[x.id] + y.len && per[y.to] < per[x.id] + p[y.to]) || dis[y.to] > dis[x.id] + y.len)
            {
                per[y.to] = per[x.id] + p[y.to];
                pre[y.to] = x.id;
                dis[y.to] = dis[x.id] + y.len;
                Q.emplace(y.to, dis[y.to]);
            }
        }
    }
}
int main()
{
    cin >> N >> M >> S >> D;
    for (int i = 0; i < N; i++)cin >> p[i];
    while (M--)
    {
        cin >> A >> B >> len;
        e[A].emplace_back(B, len);
        e[B].emplace_back(A, len);
    }
    dijkstra();
    cout << num[D] << " " << per[D] << endl << S;
    printf_path(D);
    return 0;
}

Dijkstra算法练习

公交线路 (nowcoder.com)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n,m,s,t,A,B,len;
struct edge
{
    int form,to,len;
    edge(int a,int b,int c) : form(a),to(b),len(c){};
};
vector<edge>e[maxn];
vector<int>dis(maxn,0x3f3f3f3f),pre(maxn);
bool vis[maxn];
struct q_node
{
    int id,dis;
    q_node(int a,int b):id(a),dis(b){};
    bool operator < (const q_node& s)const
    {
        return dis > s.dis;
    }
};
void dijkstra()
{
    dis[s] = 0;
    priority_queue<q_node>Q;
    Q.emplace(s,dis[s]);
    while(!Q.empty())
    {
        auto x = Q.top();
        Q.pop();
        if(vis[x.id])continue;
        vis[x.id] = true;
        for(int i = 0;i < e[x.id].size();i++)
        {
            auto y = e[x.id][i];
            if(vis[y.to])continue;
            if(dis[y.to] > x.dis + y.len)
            {
                dis[y.to] = x.dis + y.len;
                pre[y.to] = x.id;
                Q.emplace(y.to,dis[y.to]);
            }
        }
    }
}
int main()
{
    cin.tie(0)->sync_with_stdio(false);
    cin >> n >> m >> s >> t;
    while(m--)
    {
        cin >> A >> B >> len;
        e[A].emplace_back(A,B,len);
        e[B].emplace_back(B,A,len);
    }
    dijkstra();
    dis[t] == 0x3f3f3f3f ? cout << -1 << endl : cout << dis[t] << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/568947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android 12系统源码_窗口管理(二)WindowManager对窗口的管理过程

前言 上一篇我们具体分析了窗口管理者WindowManagerService的启动流程&#xff0c;对于WindowManagerService有了一个初步的认识。在此基础上&#xff0c;我本打算应该进一步分析WindowManagerService是如何管理系统中的各种窗口的&#xff0c;然而由于Android系统的架构设计&…

如何搭建远程服务器-(cpolar)

文章目录 前言一、安装注册下载安装包认证开通指定端口监听开机自启动设置 二、使用步骤电脑端远程手机端远程 三、卸载软件安装说明&#xff1a; 总结 前言 之前已经有写到一篇文章《如何用树莓派搭建远程服务器 (zerotier)》&#xff0c;对此已经使用了很长一段时间。 优点…

MySQL 事务(w字)

目录 事务 首先我们来看一个简单的问题 什么是事务 为什么会出现事务 事务的版本支持 事务提交方式 事务常见操作方式 设置隔离级别 事物操作 事物结论 事务隔离级别 理解隔离性 隔离级别 查看与设置隔离性 注意可重复读【Repeatable Read】的可能问题&#xff…

AI数字人盛行,如何选择合适的AI数字人制作平台?

2023万象大会已然开启了直播&#xff0c;当AI照进生活、照亮你我&#xff0c;为我们的想象力插上翅膀&#xff0c;世界变得更加便捷、更加智能。可以说近年来&#xff0c;AI帮助人们解决了各种问题&#xff0c;在提高生产效率、改善生活质量等方面做出来很大的贡献&#xff0c;…

LeetCode: 二叉树的直径(java)

二叉树的直径 leetcode 543题。原题链接题目描述解题代码二叉树专题 leetcode 543题。原题链接 543题&#xff1a;二叉树的直径 题目描述 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也…

WICC · 出海嘉年华|嘉宾就位、话题揭晓,峰会 派对报名倒计时

双厨狂喜&#xff01;移步【融云全球互联网通信云】回复“地图”免费领 6 月 2 日即将在广州举办的“WICC 社交泛娱乐出海嘉年华”&#xff0c;将是一场集 WICC 通信行业大会高端峰会规格、前沿技术内容和社交泛娱乐出海务实场景落地、垂直圈子社交于一体的大型盛会。 大咖嘉…

【弹性分布式EMA】在智能电网中DoS攻击和虚假数据注入攻击(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Java并发体系-锁与同步-[1]

本阶段文章讲的略微深入&#xff0c;一些基础性问题不会讲解&#xff0c;如有基础性问题不懂&#xff0c;可自行查看我前面的文章&#xff0c;或者自行学习。本篇文章比较适合校招和社招的面试&#xff0c;笔者在2020年面试的过程中&#xff0c;也确实被问到了下面的一些问题。…

c++代码实现一个高性能内存池(超详细版本)

写在前面 本文的内存池代码是改编自Nginx的内存池源码&#xff0c;思路几乎一样。由于Nginx源码的变量命名我不喜欢&#xff0c;又没有注释&#xff0c;看得我很难受。想自己写一版容易理解的代码。这应该是全网独一份的超详细版本了&#xff08;笑~&#xff09;. 应用场景 …

Java线程中的常用方法

获取当前线程的方法 为线程设置名称 为线程设置优先级&#xff0c;优先级有10个级别&#xff0c;从1-10&#xff0c;能影响cpu调用线程的级别&#xff0c;但是不能决定。 /*** author 舒一笑* date 2023/5/25*/ public class Test03 {public static void main(String[] args) …

「OceanBase 4.1 体验」|docker-compose快速部署OceanBase数据库——筑梦之路

OceanBase数据库简介 官方网站&#xff1a;https://www.oceanbase.com/softwarecenter 大名鼎鼎的OceanBase数据库&#xff0c;在多个双十一购物节上历经验证&#xff0c;今天就来体验一下当前最新版本 4.1。 OceanBase 4.1 版本技术文档&#xff1a;https://www.oceanbase.c…

How-to-generate-kernel

文章目录 前言一、协方差判断卷积核相关性问题一: 不同的样本空间&#xff1f;问题二&#xff1a;计算方式&#xff1f;想法 二、整体流程三、BSConv-核内相似性 前言 在常规卷积的过程中找到相关性低的一部分卷积核&#xff0c;利用这部分卷积核结合深度可分离卷积搭建起新的…

mycat的安装及使用

2、mycat的安装及使用 1、mycat的安装 1、环境准备 ​ 本次课程使用的虚拟机环境是centos6.5 ​ 首先准备四台虚拟机&#xff0c;安装好mysql&#xff0c;方便后续做读写分离和主从复制。 192.168.85.111 node01 192.168.85.112 node02 192.168.85.113 node03 192.168.85.…

第3章“程序的机器级表示”:数据传送指令

文章目录 3.4 访问信息3.4.1 操作数指示符3.4.2 数据传送指令3.4.3 数据传送示例 3.4 访问信息 一个 IA32 中央处理单元&#xff08;CPU&#xff09;包含一组八个存储 32 位值的寄存器&#xff0c;这些寄存器用来存储整数数据和指针。 下图显示了这八个寄存器。它们的名字都是…

element-ui拖拽上传及问题解决(drag的使用注意事项)

element-ui拖拽上传及问题解决(drag的使用注意事项) 上传组件(:drag“true”) <template><el-uploadclass"avatar-uploader"action"":show-file-list"false":on-success"handleAvatarSuccess":before-upload"beforeAva…

如何获得铁粉(弯道超车的攻略)

文章目录 一、提供有价值的内容二、保持更新频率三、与读者互动四、优化SEO五、提供专栏订阅服务 CSDN(China Software Developer Network)是中国最大的IT社区和在线学习平台之一&#xff0c;成立于1999年。它是一个面向软件开发者的知识共享社区&#xff0c;提供有关编程语言、…

Docker容器技术|最强王者篇

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

行业领先生物制药企业在冷链物流运输中采用虹科LIBERO温度记录解决方案

中国首个获得世界卫生组织国际通用名的生物Ⅰ类新药是用于抗血管内皮生长因子的融合蛋白&#xff0c;该药物通过结合血管内皮生长因子VEGF&#xff0c;竞争性抑制VEGF与受体结合并阻止VEGF家族受体的激活&#xff0c;从而抑制内皮细胞增殖和血管新生&#xff0c;达到治疗湿性年…

自学网络安全遇到问题怎么解决?路线是什么

自学网络安全很容易学着学着就迷茫了&#xff0c;找到源头问题&#xff0c;解决它就可以了&#xff0c;所以首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题&#xff0c;看到后面有惊喜哦 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xf…

什么样的程序员在 35 岁以后依然被公司抢着要?

什么样的程序员在35岁就会被优化&#xff1f; 程序员的35岁危机是一个老生常谈的话题&#xff0c;与其问什么样的程序员在35岁会被公司抢着要&#xff0c;不如踏实一点&#xff0c;来讨论下什么样的程序员在35岁之后不会被淘汰。 T0级别&#xff1a;有技术壁垒 这类人大概占程…