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

news2025/1/17 1:07:12

最短路问题的朴素版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);//1
    for (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.coloradmin.cn/o/1967922.html

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

相关文章

模型优化—动量梯度下降

一、mini-batch 梯度下降&#xff08;gradient descent&#xff09;&#xff1a; SGD&#xff08;stochastic GD&#xff09;随机梯度下降&#xff1a;对一个样本做梯度下降 batch梯度下降&#xff1a;使用所有样本做梯度下降&#xff08;做一次又叫epoch&#xff09; mini…

人工智能算法工程师(高级)课程9-自然语言处理之词嵌入的介绍与代码详解

大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程9-自然语言处理之词嵌入的介绍与代码详解。 词嵌入是一种将文本中的词语转换为数值向量的技术,广泛应用于自然语言处理领域。它通过将词语映射到多维向量空间,使得相似意义的词语在向量空间中距离较近,从…

【无标题配置jdk环境和tomcat环境

一&#xff0e;接着昨天的发布vue项目 npm run serve 构建项目 npm run build ls ls dist/ vim dist/index.html [rootweb eleme_web]# cd /usr/local/nginx/conf/ [rootweb conf]# ls 将静态的项目移动到nginx中 [rootweb nginx]# cd conf.d/ [rootweb conf.d]# ls…

用Python打造精彩动画与视频,3.3 添加音频和简单效果

3.3 添加音频和简单效果 在本节中&#xff0c;我们将学习如何使用 MoviePy 库为视频添加音频和一些简单的效果。这些操作可以让你的视频更具吸引力和个性化。 准备工作 首先&#xff0c;确保你已经安装了 MoviePy 和 pydub 库。你可以通过以下命令安装&#xff1a; pip ins…

Qt 实战(2)搭建开发环境 | 2.4、查看 Qt 源码

文章目录 一、查看 Qt 源码1、获取 Qt 源码2、添加源码路径3、配置定位器4、查看源码 前言&#xff1a; Qt 是一个跨平台的 C 图形用户界面应用程序开发框架&#xff0c;广泛应用于开发 GUI 程序以及非 GUI 程序&#xff0c;如控制台工具和服务器。查看 Qt 的源码不仅可以帮助你…

故障案例:网络访问慢

现象描述 FW作为中间设备的场景下&#xff0c;用户访问网页慢&#xff0c;报文延时大等。 相关告警与日志 相关告警 无 相关日志 ARP/4/ARP_DUPLICATE_IPADDR 原因分析 图1 网络访问慢故障定位思路 丢包 报文在网络链路上传输时&#xff0c;可能会有部分报文在链路中被丢…

用深度学习改进乳腺癌MRI诊断| 文献速递--AI辅助的放射影像疾病诊断

Title 题目 Improving breast cancer diagnostics with deep learning for MRI 用深度学习改进乳腺癌MRI诊断 01 文献速递介绍 乳腺磁共振成像&#xff08;MRI&#xff09;是一种检测乳腺癌的高度敏感的方式&#xff0c;报告的敏感性超过80%。传统上&#xff0c;其在筛查…

【算法】动态规划-斐波那契数列模型

目录 1、第N个泰波那契数 1.1 算法原理讲解 1.1.1 状态表示 1.1.2 状态转移方程 1.1.3 初始化 1.1.4 填表顺序 1.1.5 返回值 1.2 代码实现 1.3 空间优化 2、三步问题 2.1 算法原理讲解 2.1.1 状态表示 2.1.2 状态转移方程 2.1.3 初始化 2.1.4 填表顺序 2.1.5 返…

(四十一)大数据实战——spark的yarn模式生产环境部署

前言 Spark 是一个开源的分布式计算系统。它提供了高效的数据处理能力&#xff0c;支持复杂的数据分析和处理任务&#xff0c;是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。Spark Core&#xff1a;实现了Spark的基本功能&#xff0c;包含任务调度、内存管理、错误…

上线前端系统

上线一个静态的前端系统&#xff08;续&#xff09; 在eleme服务器上 启动服务 启动rpcbind [rooteleme-static ~]# systemctl restart rpcbind 启动nfs [rooteleme-static ~]# systemctl restart nfs 重启服务 启动smb [rootstatic-server img]# systemctl start smb…

SQL数据库模糊查询指定的字符的表资料(CHARINDEX)

1.目的 MSG栏位里面有很多组合内容的字符信息&#xff0c;需要进行模糊查询。 2.问题 正常使用LIKE 语句可以通用大部分的查询需求&#xff0c;但是遇到部分的特殊字符&#xff0c;例如&#xff1a;[] 资料是存在数据资料中&#xff0c;但是查询反馈的结果是没有内容&#xf…

二刷代码随想录训练营Day 16|513.找树左下角的值、112.路径总和、106.从中序与后序遍历序列构造二叉树

1.找到左下角的值 513. 找树左下角的值 - 力扣&#xff08;LeetCode&#xff09;代码随想录 (programmercarl.com) 代码&#xff1a; class Solution { public:int maxDepth INT_MIN;int result;// 深度最大&#xff0c;确保是最后一行 先遍历左孩子再遍历右孩子 确保是左下…

进程地址空间,零基础最最最详解

目录 建议全文阅读&#xff01;&#xff01;&#xff01; 建议全文阅读&#xff01;&#xff01;&#xff01; 建议全文阅读&#xff01;&#xff01;&#xff01; 一、什么是地址空间 1、概念 2、主要组成部分 3、特点和作用 &#xff08;1&#xff09;虚拟化&#xf…

Java并发—volatile关键字

在这篇文章Java并发—Java内存模型以及线程安全-CSDN博客多次提及volatile关键字&#xff0c;这是一个非常重要的概念&#xff0c;主要用于多线程编程中&#xff0c;它确保了变量的可见性和禁止指令重排序&#xff0c;但不保证原子性&#xff0c;下面详细解释volatile关键字的作…

未来3-5年,哪些工作会被AI取代

一篇由高盛经济学家约瑟夫布里格斯 &#xff08;Joseph Briggs&#xff09;和德维西科德纳尼 &#xff08;Devesh Kodnani&#xff09;撰写的报告指出&#xff0c;全球预计将有3亿个工作岗位被生成式AI取代。 报告称&#xff1a;“最近出现的生成式人工智能将降低劳动力成本和…

​宁德时代:续航还剩多少?

车企价格战打到供应商&#xff0c;连续增利不增收。 今天我们看宁德时代的增长电池续航还剩多少&#xff1f; 巨头长成&#xff0c;就要面临增长瓶颈。“宁王”24年中报公布&#xff0c;业绩喜忧参半。二季度营收869.96亿&#xff0c;同比下滑13.18%&#xff0c; 已经是宁德时…

冠军之选:奥运冠军青睐的游泳耳机款式大公开

在最新一届的夏季奥林匹克运动会中&#xff0c;泳池边的激烈竞争再次点燃了全球观众的热情。游泳运动员们&#xff0c;以惊人的速度和毅力&#xff0c;一次又一次地刷新纪录&#xff0c;向世人展示了人类极限的无限可能。而在这些运动员备战的过程中&#xff0c;有一个细节或许…

吴恩达老师机器学习-ex5

有借鉴网上部分博客 首先&#xff0c;我先使用该数据集&#xff0c;通过线性回归的方法&#xff0c;做了一个预测问题 import numpy as np import scipy.io as sio import matplotlib.pyplot as plt from scipy.optimize import minimize#读取数据 path "./ex5data1.ma…

Spine 核心功能入门

核心功能入门 本文主旨是整理我在入手学习 spine 时的流程&#xff0c;以及对于基本功能的理解和常规 2D 动画实现的思路。 意在整理出一个简要的入门 spine 的流程&#xff0c;以及对于一些高阶功能的应用的思考。 本文基于 https://zh.esotericsoftware.com/ 官网教程进行思…

2024.8.1 作业

使用两个线程完成两个文件的拷贝&#xff0c;分支线程1拷贝前一半&#xff0c;分支线程2拷贝后一半&#xff0c;主线程回收两个分支线程的资源 #include <myhead.h>struct Buf {const char *file1;const char *file2;int start;int size; };int get_len(const char *arr…