【算法】Dijkstra求最短路算法

TOP提示:Dijkstra算法只适用于不含负权边的情况 

Dijkstra算法是一个基于贪心,广搜和动态规划 求图中某点到其他所有点的最短路径的算法 

一、步骤

首先我们先总结Dijkstra算法的完整步骤

我们需要一个dis数组存储从起点到达其他节点的最短距离,一个check数组判断从起点到某点的最短距离是否已确定,一个path二维数组存储图中从点 i 到点 j 的距离

一共循环n次(n个节点),起初将从起点到其他所有节点的距离(dis[i])初始化为最大值。

每次循环从dis数组中未确定最短路径的所有点中找出最小值的下标mini(第一次循环时最小值为起点dis[1],因为起点到自己的距离为0,其他的都初始化为了最大值),此时该最小值即为起点到该点的最短路径,在check数组中标记该点,然后计算从该点出发到达其他节点的距离,如果比原来的值更小则更新dis数组。

二、原理

贪心是其中的重要思想,为什么每次找出的最小值就是起点到该点的最短路径呢?

这就要提到为什么Dijkstra不适用于含负权边的情况了,当边的权值全部为正时,从起点经过其他的点到达最小值点的路径长度必定会大于原来的这个最小值!

例如你从起点到A点的最短路径是100,到B点的最短路径是200,那么你从起点经过B点到达A点的距离可能会比直接从起点到A点的距离短吗?除非从B点到A点的距离为负数。 

所以当我们每次扫描未确定最短路径中的所有点,找出其中的最小值,该最小值就是起点到达该点的最短路径。经过n次循环,我们就能找出起点到达所有点的最短路径 

我们以下面这道题为例实战一下:

完整代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 510;

int n, m, dis[N];
int path[N][N];
bool check[N];

int dijkstra()
{
    memset(dis, 0x3f, sizeof dis); //将起点到其他点的路径初始化为最大值
    dis[1] = 0; //起点到自己的距离为0
    for(int i = 1;i <= n;i++) //n次循环
    {
        int mini = -1; 
        for(int j = 1; j <= n;j++)
        {
            if(!check[j] && (mini == -1 || dis[mini] > dis[j]))
            //从未确定最短距离的点中取出最小值
                mini = j;
        }
        
        check[mini] = true; //标记该点为已确定
        
        for(int j = 1;j <= n;j++)
        {
            //以该点为基础更新其他所有点的最短距离
            dis[j] = min(dis[j], dis[mini] + path[mini][j]);
        }
    }
    if(dis[n] == 0x3f3f3f3f) return -1; //如果n号点的距离还是为最大值,说明无法到达
    return dis[n];
}

int main()
{
    //题目中说可能存在重边,所以将边的权值初始化为最大值便于比较
    memset(path, 0x3f, sizeof path);
    cin >> n >> m;
    for(int i = 1;i <= m;i++)
    {
        int a, b ,c;
        cin >> a >> b >> c;
        path[a][b] = min(path[a][b], c); //如果重边,取最小值
    }
    
    int t = dijkstra(); //Dijkstra算法
    
    cout << t << endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用字符串初始化的指针

一. 简介 前一篇文章简单学习了数组与指针的区别&#xff0c;文章如下&#xff1a; C语言中数组与指针的区别-CSDN博客 本文学习一下 初始化为 字符串的 指针。防止使用过程中出现问题。 二. 初始化指针来指向字符串 初始化指针来指向字符串&#xff0c;例如如下代码就是…

力扣每日一题-收集垃圾的最少总时间-2024.5.11

力扣题目&#xff1a;收集垃圾的最少总时间 题目链接: 2391.收集垃圾的最少总时间 题目描述 代码纯享版 class Solution {public int garbageCollection(String[] garbage, int[] travel) {int sum 0;int last_M -1,last_P -1, last_G -1;for(int i 0; i < garbage.…

HTML【安装HBuilder、常用标签】--学习JavaEE的day44

day44 JavaEE 学习过程&#xff1a;前端—>数据库—>服务器端 前端的VUE在框架阶段学习 JavaEE学习过程图 HTML 前端&#xff1a;展示页面、与用户交互 — HTML 后端&#xff1a;数据的交互和传递 — JavaEE/JavaWeb 1. 前端开发的工作模式 开发输出htmlcssjs 理解&am…

Springboot+Vue项目-基于Java+MySQL的宠物商城网站系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

【未公开】电信网关配置管理系统rewrite接口存在文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【JavaScript】内置对象 - 数组对象 ⑤ ( 数组转字符串 | toString 方法 | join 方法 )

文章目录 一、数组转字符串1、数组转字符串 ( 逗号分割 ) - toString()2、数组转字符串 ( 自定义分割符 ) - join() Array 数组对象参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array 一、数组转字符串 1、数组转字符串 ( 逗…

#04 构建您的第一个神经网络:PyTorch入门指南

文章目录 前言理论基础神经网络层的组成前向传播与反向传播 神经网络设计步骤1&#xff1a;准备数据集步骤2&#xff1a;构建模型步骤3&#xff1a;定义损失函数和优化器步骤4&#xff1a;训练模型步骤5&#xff1a;评估模型结论 前言 在过去的几天里&#xff0c;我们深入了解了…

【Java】获取近六个月的年月

数据库里面存储的字段类型就是varchar&#xff0c;数据格式就是类似2024-12这样的年月格式。 目标&#xff1a; 以当前月份为标准&#xff0c;向前获取近6个月的年月&#xff08;year_month&#xff09;形成列表 // 获取近6个月的年月列表List<String> recentMonths ge…

fswatch工具:跟踪Linux中的文件和目录更改

fswatch是一个跨平台的文件更改监视器&#xff0c;当指定文件或目录的内容被更改或修改时&#xff0c;它会收到通知警报。 fswatch在不同的操作系统上执行多种类型的监视器&#xff0c;例如&#xff1a; 基于 Apple OS X 的文件系统事件 API 构建的监视器。基于kqueue的监视器…

Nginx部署前后端分离项目

部署前后端分离项目&#xff0c;要求前端项目、后端项目、数据库分别部署在3台服务器 服务器准备 服务器名IP软件包前端192.168.99.137nginx后端192.168.99.139jar数据库192.168.99.100mariadb 1、前端服务器 yum install -y epel-release && yum install -y nginx…

9.spring-图书管理系统

文章目录 1.开发项目流程1.1开发开发1.2数据库的设计 2.MySQL数据库相关代码3.构造图书结构3.1用户登录3.2图书列表3.3图书添加3.4图书删除3.4.1批量删除 3.5图书查询(翻页) 4.页面展示4.1登录页面4.2列表页面4.3增加图书页面4.4修改图书信息页面 5.功能展示5.1增加图书信息5.2…

分布式与一致性协议之TCC协议

TCC协议 概述 虽然MySQL XA能实现数据层的分布式事务&#xff0c;解决多个MySQL操作的事务问题&#xff0c;但还面临别的问题:在接收到外部的指令后&#xff0c;需要访问多个内部系统&#xff0c;执行指令约定的操作&#xff0c;还必须保证指令执行的原子性(也就是事务要么全…

nestjs 全栈进阶--中间件

视频教程 22_nest中中间件_哔哩哔哩_bilibili 1. 介绍 在Nest.js框架中&#xff0c;中间件&#xff08;Middleware&#xff09;是一个非常重要的概念&#xff0c;它是HTTP请求和响应生命周期中的一个重要组成部分&#xff0c;允许开发者在请求到达最终的目的控制器方法之前或…

机器学习算法 - 逻辑回归

逻辑回归是一种广泛应用于统计学和机器学习领域的回归分析方法&#xff0c;主要用于处理二分类问题。它的目的是找到一个最佳拟合模型来预测一个事件的发生概率。以下是逻辑回归的一些核心要点&#xff1a; 基本概念 输出&#xff1a;逻辑回归模型的输出是一个介于0和1之间的…

【数据结构】队列详解(Queue)

文章目录 有关队列的概念队列的结点设计及初始化队列的销毁判空和计数入队操作出队操作 有关队列的概念 队列:只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out)入队列:进行插入操作的一端…

Redis不同数据类型value存储

一、Strings redis中String的底层没有用c的char来实现&#xff0c;而是使用SDS数据结构( char buf[])。 缺点:浪费空间 优势: 1.c字符串不记录自身的长度&#xff0c;所以获取一个字符串长度的复杂度是O(N),但是SDS记录分配的长度alloc,已使用长度len&#xff0c;获取长度的…

CSS文字描边,文字间隔,div自定义形状切割

clip-path: polygon( 0 0, 68% 0, 100% 32%, 100% 100%, 0 100% );//这里切割出来是少一角的正方形 letter-spacing: 1vw; //文字间隔 -webkit-text-stroke: 1px #fff; //文字描边1px uniapp微信小程序顶部导航栏设置透明&#xff0c;下拉改变透明度 onP…

[js] 递归,数组对象根据某个值进行升序或者降序

一、效果图 1.1 父级 1.2 父级与子级 二、代码 升序降序&#xff0c;只要把 a.num - b.num 改成 b.num - a.num <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, i…

pycharm 将项目连同库一起打包及虚拟环境的使用

目录 一、创建虚拟环境 1、用 anaconda 创建 2、Pycharm 直接创建 二、虚拟环境安装第三方库 1、创建项目后&#xff0c;启动终端(Alt F12)&#xff0c;或者点击下方标记处。 2、使用 pip 或者 conda 来进行三方库的安装或卸载 3、将项目中的库放入文档&#xff0c;便于…

Dual Aggregation Transformer for Image Super-Resolution论文总结

题目&#xff1a;Dual Aggregation Transformer&#xff08;双聚合Transformer&#xff09; for Image Super-Resolution&#xff08;图像超分辨&#xff09; 论文&#xff08;ICCV&#xff09;&#xff1a;Chen_Dual_Aggregation_Transformer_for_Image_Super-Resolution_ICCV…