最短路问题中的朴素版Dijkstra算法

最短路问题的朴素版Dijkstra算法

  • 题目

最短路问题需要用到下面的算法(n代表点的数量,m代表边的数量)
在这里插入图片描述
朴素版和堆优化版的Dijkstra算法的区别是,朴素版比较适合稠密图,堆优化版适合稀疏图,稠密图代表它的边比较多,边的数量最多是点的平方,稀疏图代表边基本于点的数量差不多。


对于下面的这个题,就需要用到朴素版的Dijkstra算法。

题目

给定一个 n n n 个点 m m m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出 1 1 1 号点到 n n n 号点的最短距离,如果无法从 1 1 1 号点走到 n n n 号点,则输出 − 1 -1 1

输入格式

第一行包含整数 n n n m m m

接下来 m m m 行每行包含三个整数 x , y , z x,y,z x,y,z,表示存在一条从点 x x x 到点 y y y 的有向边,边长为 z z z

输出格式

输出一个整数,表示 1 1 1 号点到 n n n 号点的最短距离。

如果路径不存在,则输出 − 1 -1 1

数据范围

1 ≤ n ≤ 500 1 \le n \le 500 1n500,
1 ≤ m ≤ 1 0 5 1 \le m \le 10^5 1m105,
图中涉及边长均不超过10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

朴素版的Dijkstra思路如下:

  1. 将所有点到1号点的距离设置为正无穷(一个很大的数,当做正无穷看待,并不是真正的正无穷),将1号点的距离设置成0。
  2. 首先外层遍历 n 次循环
  3. 每次循环找到一个集合外的点当中距离离1最近的点,假设是 t
  4. 把该点放到集合当中
  5. 利用t更新 与 t 连接的点

在这里插入图片描述

存储稠密图需要用到邻接矩阵存储,g[a] [b] 代表 a点 到 b 点的距离。

数组 dist 用来存储n号点到 1号点的距离,st 代表该点是在集合内还是集合外。

一般建议每次将题目的点的数量写成N,将边写成 M,并且尽量在原有最大数据上 加一点数字,我这里都多了10,是为了防止出现数组不够的情况


首先是 输入环节,开始将整个图存起来
在这里插入图片描述
由于题目当中会含有重边,所以我们需要 2 号语句,只算最小的那条边,由于这样最开始的 二维数组未初始化,所以值都是0,所以我们需要用 1 号语句,将所有值变为 正无穷大,这样就不会求最小值是0了,而且写1号语句的也不仅如此,还关系到点的更新,所以必须进行初始化

我们可以用 0x3f3f3f3f 当做无穷大,这个数作为无穷大的好处是 乘以2之后不会溢出 int 的范围,并且该数字很大。
在这里插入图片描述
memset 里面的是 0x3f 的原因是 memset 设置的是每个字节的值,所以每个字节是 0x3f,int 类型是4个字节,所以就是 0x3f3f3f3f。

在这里插入图片描述
dijkstra函数执行完之后,数组 dist[ n ]存的就是 1号点到 n 号点的距离。

在dijkstra 函数内部我们会将 dist数组当中所有的值设置成 正无穷大,也就是0x3f3f3f3f,所以如果当dist[n]还是正无穷大时,也就证明1号点走不到 n 号点,没有点更新 n号点。

根据题目要求走不到则打印 -1

在这里插入图片描述
在dijkstra函数中,就需要用到刚才的思路。

第一步,将数组 dist 中的值 设置为正无穷大(跟刚才设置数组g 一样),将1号点的距离设为1。

接着外层for循环 到 n
在这里插入图片描述
在循环内部有 三个步骤。

  1. 每次找到所有集合外的点当中距离最近的点
    在这里插入图片描述
    变量 t 为每次最近的点,遍历一遍所有的点,!st[j] 代表在集合外,如果当 t 还是 -1 或 当 t 这个点的距离遇到更小的距离的时候,则将 j 赋值给 t。

    此时 t 点就是距离最近的点

  2. 第二步 将该点放到集合当中,代表着它的距离已经确定了。

在这里插入图片描述
数组 st 的含义就是代表该点是否在集合里,所以只需要将 t 点设为 true 即可

  1. 第三步,利用 t 点更新其他可以更新的点

在这里插入图片描述
这里也解释了为什么 数组 g 要设置成正无穷大,正无穷大的含义相当于 t 点 与 j 点没有直接练在一起。

所以如果没有连在一起,那么也就不会更新。

也就是说,这一步,遍历了所有的点,看一看能不能 用 t 更新它,如果 1号点到 t点 的距离加上 t到 j 的距离 小于1号点到 j点的距离,那么就会更新。

在这里插入图片描述
比如这里原来 j 号点到 1 的距离是 2 + 4 = 6,此时 t 到1的距离为3,加上 t 到 j 的距离 1 为 4,因为小于6,所以就会更新 j 到 1 的距离。


最后还可以进行一点小小的优化,不优化也没任何问题
在这里插入图片描述
更新 n - 1 次的时候, n 号点 就必定会被更新,当然前提能到达的情况下,因为每次都找一个集合外最近的点。

当找到 最近的点为 n 时,说明此时 n 号点的距离就已经确定了,所以可以直接break出去。


完整代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 510, M = 1e5+10;int g[N][N];
int dist[N];
bool st[N];int n, m;void dijkstra()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < n - 1; i++){//1.找到距离最近的点int t = -1;for (int j = 1; j <= n; j++)if (!st[j] && (t == -1 || dist[t] > dist[j]))t = j;if (t == n) break;//2.将距离最近的点放到集合当中st[t] = true;//3.更新点for (int j = 1; j <= n; j++)if (!st[j])dist[j] = min(dist[j], dist[t] + g[t][j]);}
}int main()
{scanf("%d%d", &n, &m);memset(g, 0x3f, sizeof g);//1for (int i = 0; i < m; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);g[a][b] = min(g[a][b], c);//2}dijkstra();if (dist[n] == 0x3f3f3f3f) puts("-1");else printf("%d\n", dist[n]);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python | TypeError: list indices must be integers or slices, not tuple

python | TypeError: list indices must be integers or slices, not tuple 在Python编程中&#xff0c;TypeError: list indices must be integers or slices, not tuple 是一个常见的错误。此错误通常发生在尝试使用非整数&#xff08;如元组&#xff09;作为列表索引时。本…

RK3568笔记四十九:W25Q64驱动开发(硬件SPI1)

若该文为原创文章&#xff0c;转载请注明原文出处。 一、SPI介绍 串行外设接口 (Serial Peripheral interface) 简称 SPI&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并 且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚。 …

Python写UI自动化--playwright(在UI元素上悬停)

要在UI元素上执行鼠标悬停&#xff08;hover&#xff09;动作&#xff0c;可以使用page.hover()方法。这个方法使鼠标指针移动到指定的元素上&#xff0c;就像用户将鼠标悬停在该元素上一样。这对于触发那些依赖于鼠标悬停事件的行为&#xff08;如显示下拉菜单、提示框或其他动…

[极客大挑战 2019]PHP1

打开题目 游戏界面 猜测php里面有文件&#xff0c;我们可以用dirsearch 扫描一下这个服务器 执行命令 dirsearch -u http://2999dfd5-1d43-4a81-a088-9e41c9dccab4.node4.buuoj.cn/ -e php > test.log 最后在log文件中找到一个 200 www.zip 浏览器输入payload下载下来 …

操作系统_内存管理学习心得

1. 操作系统结构 1.1 内核 计算机是由各种外部硬件设备组成的,比如内存、cpu、 硬盘等,如果每个应用都要和这些硬件设备对接通信协议&#xff0c;那这样太累了&#xff0c;所以这个中间人就由内核来负责,让内核作为应用连接硬件设备的桥梁,应用程序只需关心与内核交写&#x…

C++ | Leetcode C++题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution { public:void moveZeroes(vector<int>& nums) {int n nums.size(), left 0, right 0;while (right < n) {if (nums[right]) {swap(nums[left], nums[right]);left;}right;}} };

SpringBoot集成GraalVM创建高性能原生镜像

1. GraalVM 原生镜像的介绍 GraalVM原生镜像为部署和运行Java应用程序提供了一种新的方式。与Java虚拟机相比&#xff0c;原生镜像可以以更小的内存占用和更快的启动时间运行。 它们非常适用于使用容器镜像部署的应用程序&#xff0c;当与 "功能即服务"&#xff08…

短剧系统源码分享,快速搭建部署上线教程

一、短剧系统是什么&#xff1f; 短剧制作平台&#xff0c;作为一站式综合解决方案&#xff0c;集剧本创作、角色设计、场景搭建、视频编辑、便捷发布及深度数据分析能力于一身。该平台精准定位于助力企业利用短剧形式强化品牌传播力并驱动商业价值增长&#xff0c;无论企业是…

什么是IO多路复用?其原理和用途是什么?

什么是IO&#xff1f; IO&#xff1a;Input/Output&#xff0c;即数据的读取&#xff08;接收&#xff09;/写入&#xff08;发送&#xff09;操作&#xff0c;针对不同的数据存储媒介&#xff0c;大致可以分为网络 IO 和磁盘 IO 两种。在 Linux 系统中&#xff0c;为了保证系…

关于Excel表格隔行取列的方法

关于Excel表格隔行取列的方法 1、场景显示2、参考文章 1、场景显示 ①处的公式&#xff1a; INDEX($B3:$G3,(COLUMN(A1)*2)) $B与$G可以限制列不变&#xff1b; COLUMN(A1)返回1&#xff1b; 含义&#xff1a; 在选定区域选择偶数列的数据&#xff1b; 如果是奇数列的话是(COL…

查看RAM和Flash

0 Preface/Foreword 1 查看方法 1.1 map文件中查看 1.1.1 RAM可用情况 在map文件中&#xff0c;搜索字符串&#xff1a;free_ramcp 该字段表示剩余可用的RAM大小&#xff0c;前面对应的是hexadecimal的数值&#xff08;单位Byte&#xff09;&#xff0c;就是剩余可用的RA…

乱弹篇(39)请珍惜懂你的人

今日清晨&#xff0c;笔者照常去到古镇味江河畔垂钓&#xff0c;呼吸着凉爽晨风轻轻吹拂而来的大自然氧吧生产出的优质氧气......忽地&#xff0c;记起已经许久未履行义务了&#xff0c;所以本“人民体验官”今天要推广人民日报官方微博文化产品《有个真朋友是一生的福气》。 截…

Redis:十大数据类型

键&#xff08;key&#xff09; 常用命令 1. 字符串&#xff08;String&#xff09; 1.1 基本命令 set key value 如下&#xff1a;设置kv键值对&#xff0c;存货时长为30秒 get key mset key value [key value ...]mget key [key ...] 同时设置或者获取多个键值对 getrange…

实验21.实现 printf

已完成实验 已完成实验链接 简介 实验 21. 实现 printf 总结 简化系统调用和中断&#xff0c;用 eax 代表调用号参数&#xff0c;ebx,ecx,edx 来代表参数(syscall.c kernel.s) 添加 write 的系统调用接口(syscall.c, syscall-init.c, print.s) 注意&#xff1a;要更改 p…

基于N32L406MB EasyFlash参数(key-value)记录库移植

EasyFlash 感谢作者的分享https://github.com/armink/EasyFlash EasyFlash是一款开源的轻量级嵌入式Flash存储器库&#xff0c;方便开发者更加轻松的实现基于Flash存储器的常见应用开发 三大实用功能 ENV快速保存产品参数(key-value)&#xff0c;支持 写平衡&#xff08;磨…

最小例程上加OLED显示

最小例程上加OLED显示 本工程代码链接: https://ww0.lanzoul.com/i8lNa265gj7g 失效联系:qq2958360390 我们其实就加上这几个文件, 然后会调用就可以了, 具体的就看江协科技的OLED, 讲的很清楚, 我们这里只说应用, 我们的重点在使用. 下面跟着我来, 复制黏贴: 更详细请看哔哩…

从零开始学习机器学习,掌握AI未来的关键!

从零开始学习机器学习 1. 介绍1.1 人工智能&#xff08;AI&#xff09;概述1.2 机器学习在人工智能中的应用1.3 机器学习基础概念 2. 监督学习2.1 什么是监督学习2.2 回归分析2.3 分类问题2.4 模型评估和选择 3. 无监督学习3.1 什么是无监督学习3.2 聚类算法3.3 降维技术 4. 深…

(39)智能电池

文章目录 前言 1 通过任务规划器进行设置 2 补充信息 3 限制条件 4 参数说明 前言 虽然还不是很普遍&#xff0c;但智能电池更容易从飞行器上安装和拆卸&#xff0c;并且能够提供更多关于电池状态的信息&#xff0c;包括容量、单个电池电压、温度等。 ArduPilot 支持几种…

qt的信号槽连接成功,但是就是无法触发槽函数。你必须使用connect的第5个参数,Qt::QueuedConnection

signals:void sends(); public slots:void sl();//这种是默认自动连接&#xff0c;故第五个参数不用写connect(this,&MainWindow::sends,this,&MainWindow::sl);emit sends();void sl() {}如果connect连接成功&#xff0c;但是无法触发槽函数。你应该使用第五个参数&…

【vue-cli】vue-cli@2源码学习

vue-cli 2 源码 @vue/cli: 3.11.0创建项目 vue create 项目名称 @vue/cli: 2.x.x 创建项目 vue init webpack yhh-project 脚手架初始化项目流程: 下载vue/cli@2 源码 下载完成后初始化 npm i 创建项目 vue init webpack yhh-project vue-init: bin/vue-init #!/usr/bin/e…