dijkstra其实是bfs?--重新定义dijkstra

news2024/9/23 7:33:56

dijkstra其实是bfs?--重新定义dijkstra

  • 1前言
  • 2最短路径问题
  • 3没有边权的最短路--bfs算法
  • 4边权的加入
  • 5优先队列与dijkstra
  • 6后记

1前言

本文将介绍dijkstra算法全新的理解方式
建议新手对dijkstra有建议了解,强烈推荐这篇文章,无比详细

2最短路径问题

最短路径问题,顾名思义,就是在图上找一条从起点到终点的最短路径
最短路径问题也有不同的分类
我们今天将研究的,是解决单源最短路最常用的算法–dijkstra

3没有边权的最短路–bfs算法

有些最短路问题,所有边都没有边权,可以视为边权为 1 1 1
这也是最短路最简单的问题,甚至可以称为图的遍历的模板
那么,广度优先搜索bfs算法的原理是什么呢?
将图分层(如图)
(bfs分层图的思想在网络流问题中也有体现,建议阅读)
在这里插入图片描述
每个点的层次用蓝色标注
很容易得 1 − 7 1-7 17的最短路径长度为 4 4 4
但是,点 5 5 5也可以由 4 4 4到达,为什么不把它划分到第四层呢
这就要说到bfs中的队列了
众所周知,队列是一种FIFO(first in first out,先进先出)的数据结构
每搜到一个点,就先入队, 2 2 2显然比 4 4 4先入队,就要先出队,来更新 5 5 5
我们关注队列里的元素,它们对应的层次单调不减
我们存储一下入队的顺序,就是图的bfs序
也就是说,优先选取层次小的点来更新,这就是bfs

4边权的加入

我们为这些边增加权值
如下图(边权用蓝色标出)
在这里插入图片描述
我们再用bfs跑一遍, 2 2 2点先更新 5 5 5
标记 1 1 1点到 5 5 5点的最短路径为 5 5 5
但是此时,我们先走 4 4 4,你就会发现,路径长度仅为 4 4 4,更短了
我们的bfs就这样在带权图里被hack了…

5优先队列与dijkstra

看到这里,想必你也知道了,此时bfs队列里的值不再具有单调性
那怎么办?
还记得优先队列(堆)吗,可以动态维护队列内的最值(堆的原理便不再赘述)
我们把队列换成优先队列不就好了吗
这就是dijkstra,一个优先队列优化的bfs
所有人都告诉你dijkstra用堆是来优化的
可是我认为,有堆的dijkstra才是真正的dijkstra
但是,怎么确定有没有更小的值还没入队呢
这里就要说到dijkstra的精髓了
首先,所有在未来可能入堆的值都由现在的值直接或间接得到
路不可能越走越短,所以在堆的外面没用更小值
但是,我们还要存一下起点到每个点的最短路径,因为可能出现一个点更新多次的情况
这下再用堆,算法就成了…吗?
如果有边的边权是负数呢
显然用不了dijkstra,这就要用spfa
但是一般情况边权是正的,要用dijkstra!会卡spfa!
附代码(c++)

#include<bits/stdc++.h>
using namespace std;
const int Max=1e5+100;
struct node{
    int nxt,v,w;
}a[Max*2];
struct lis{
    int val,id;
};
bool operator<(const lis &u,const lis &v){
    return u.val>v.val;
}
bool vis[Max];
int head[Max*2],cnt;
int dis[Max];
void add(int u,int v,int w){
    a[++cnt]={head[u],v,w};
    head[u]=cnt;
}
void dijkstra(int s,int n){
    priority_queue<lis>q;
    memset(dis,63,sizeof(dis));
    vis[s]=0;
    dis[s]=0;
    q.push({0,s});
    while(!q.empty()){
        int k=q.top().id;
        q.pop();
        if(vis[k])continue;
        vis[k]=1;
        for(int i=head[k];i!=0;i=a[i].nxt){
            int v=a[i].v,w=a[i].w;
            if(dis[v]>dis[k]+w){
                dis[v]=dis[k]+w;
                q.push({dis[v],v});
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int n,m;
    cin >> n >> m;
    for(int i=0;i<m;i++){
        int x,y,z;
        cin >> x >> y >> z;
        add(x,y,z);
    }
    dijkstra(1,n);
    cout << dis[n]; 
    return 0;
}

6后记

作者把dijkstra看成bfs的行为可能存在问题,如有错误请各位神犇指点
关注CSDN@森林古猿1,看更多c++教学
森林古猿出品,必属精品,请认准CSDN@森林古猿1

关注CSDN@一个很不专业的编程小白,c++算法超详解

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

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

相关文章

sql注入sqli-labs第二-四关

目录 sql注入sqli-labs第二关 1、了解表的列数 2、连表查询 3、注入管理员账号密码 sql注入sqli-labs第三关 1、逃脱单引号&#xff0c;括号 ​编辑 2、了解表的列数 3、连表查询 4、注入管理员账号密码 sql注入sqli-labs第四关 1、逃脱双引号&#xff0c;括号 2、了…

3GPP入门

官网地址 3GPP – The Mobile Broadband Standard 协议下载链接 Directory Listing /ftp/specs/archive 总纲 重点series Signalling protocols ("stage 3") - user equipment to network24 series信令Radio aspects25 series3G 基础LTE (Evolved UTRA), LTE-Adva…

RCNA | RGOS日常管理和Windows常用网络命令

RCNA | RGOS日常管理和Windows常用网络命令 一、RGOS日常管理操作1. RGOS平台平台概述2. 常用登陆方式3. CLI模式 二、Windows常用网络命令1. ICMP协议2. Ping命令3. Tracert命令4. Windows其他命令 一、RGOS日常管理操作 RGOS操作系统最主要的三大特性是模块化、安全性、开放性…

anaconda下载库的方法

首先打开anaconda prompt&#xff08;桌面搜索&#xff09;&#xff0c;输入 conda activate &#xff08;项目名字&#xff09;然后pip install

ARMxy工控机使用Node-Red教程:开发环境、应用场景(1)

开发环境 Windows 开发环境&#xff1a;Windows 7 64bit 、Windows 10 64bit Linux 开发环境&#xff1a;Ubuntu18.04.4 64bit U-Boot&#xff1a;U-Boot 2018 Kernel &#xff1a;Linux-4.9.170 LinuxSDK&#xff1a;LinuxSDK-[版本号].tar.gz&#xff08;基于全志官方&a…

最新!2024年—华为认证HCIA考试报名攻略分享

HCIA HCIA是华为初级认证。HCIA认证定位于中小型网络的设计、实施和维护&#xff0c;也是三种级别认证中最初级的认证。 HCIA方向 HCIA认证条件 无 HCIA认证考试 考试代码: H12-811 考试类型: 笔试&#xff08;一科&#xff09; 试卷题型: 单选题、多选题、判断题、填空题…

DevOps 的起源

注&#xff1a;机翻&#xff0c;未校。 The Origins of DevOps: What’s in a Name? As DevOps prepares for its second decade of existence, it might be worth a stroll down memory lane to revisit the origins of DevOps methods—and even the term itself. 随着DevO…

时光不等人:java每日一练

题目 选自牛客网 1.final方法等同于private方法。&#xff08; &#xff09; A.正确 B.错误 正确答案&#xff1a;B final方法和private方法并不等同。final修饰的方法表示该方法不能被子类覆盖&#xff08;override&#xff09;&#xff0c;但仍然可以被访问。而private修饰…

Redis02——缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、缓存工具封装)

目录 缓存概念 添加Redis缓存 业务场景 缓存作用模型 java代码 缓存更新策略 主动更新的三种策略 主动更新——Cache Aside Pattern 实际应用 缓存穿透 概念 解决方法 实际应用 缓存雪崩 概念 解决方法 缓存击穿 互斥锁 介绍 实际应用 逻辑过期 介绍 实际…

【单片机毕业设计选题24101】-基于单片机的车载事故报警系统

系统功能: 系统上电后&#xff0c;OLED显示“欢迎使用请稍后”两秒后显示“Wait SIM900A”, SIM900A模块初始化OK后进入正常界面显示。 第一行显示采集到的温湿度值 第二行显示系统状态&#xff08;OK或Alarm&#xff09; 第三行显示经度值 第四行显示纬度值 注意经纬度信…

dll文件丢失怎么恢复?超简单的5个方法,1分钟搞定dll文件修复!

DLL&#xff0c;或称动态链接库&#xff0c;是一种重要的文件类型&#xff0c;包含了一系列用于运行几乎所有程序的指令&#xff0c;这些程序在win11、win10、win8和win7系统中都广泛使用。如果Windows操作系统中的dll文件丢失&#xff0c;您可能无法正常启动所需的程序或应用。…

劳易测高防护等级的读码系统提升仓储效率

在现代物流与仓储管理领域&#xff0c;条码识别和数据交换系统已经成为实现智能仓储管理的关键技术。面对特定的工业环境挑战&#xff0c;比如腐蚀性气雾等恶劣条件&#xff0c;具备高防护等级和抗腐蚀能力的条码系统显得尤为重要。今天&#xff0c;小易将为您带来创新的解决方…

Zabbix中文乱码问题解决方案

WinR打开运行&#xff0c;输入fonts&#xff0c;回车进入Windows字体目录&#xff0c;找到微软雅黑-常规字体&#xff0c;复制出来将文件名修改为msyh.ttf&#xff0c;注意后缀ttf 将msyh.ttf上传到服务器zabbix字体目录中&#xff1a;/usr/share/zabbix/fonts/ 注意文件权限 …

代码随想录训练营第五十二天 孤岛的总面积

第一题&#xff1a;孤岛的总面积 第二题&#xff1a;沉没孤岛 思路&#xff1a; 将所有在边界的岛屿所在的visited数组位置都置为true&#xff0c;剩下的visited[i][j] true && grid[i][j] 1的位置就是孤岛&#xff0c;将其置为1即可。 代码如下 #include <io…

WiFi to Ethernet: 树莓派共享无线连接至有线网口,自动通过Captive Poartal网页登录认证

物联网开发系列&#xff1a;物联网开发之旅① WiFi to Ethernet: 树莓派共享无线连接至有线网口&#xff0c;自动通过Captive Poartal验证物联网开发番外篇之 Captive Portal验证原理 文章目录 背景实现工具实现细节一、将无线连接共享到以太网1. 配置静态IP地址2. 启用IP转发3…

Chainlit快速实现AI对话应用的聊天记录如何持久性保存

前言 Chainlit 可以设置聊天记录用户搜索和浏览过去的对话。 如何实现 要启用聊天历史记录,您需要启用: 数据持久性身份验证恢复对话 为了让用户继续持久对话,请使用cl.on_chat_resume 生命周期钩子 装饰器使用户能够继续对话。需要同时启用数据持久性和身份验证。 该…

day21(mysql用户创建与授权、角色创建)

1.环境准备 [rootmysql ~]# rm -rf /etc/my.cnf //清空/etc目录下的my.cnf [rootmysql ~]# yum -y remove mariadb //移除mariadb [rootmysql ~]# find / -name "*mysql*" -exec rm -rf {} \; //删除mysql所有遗留 文件 2.安装绿色mysql [rootmysql ~]# t…

安装svd模型

svd模型简介 Stable Video Diffusion模型基于潜在的视频扩散模型&#xff0c;通过在小型、高质量的视频数据集上插入时间层并进行微调&#xff0c;将传统的2D图像合成模型转化为生成视频模型。这种方法的优点在于&#xff0c;它能够生成高分辨率的视频&#xff0c;并且具有强大…

C++基础编程100题-034 OpenJudge-1.4-15 最大数输出

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0104/15/ 描述 输入三个整数,输出最大的数。 输入 输入为一行&#xff0c;包含三个整数&#xff0c;数与数之间以一个空格分开。 输出 输出一行&#xff0c;包含一个整数&#xff0c;即最大的整数。 样例…

【AI】关于AI和手机

2011 年至2015 年期间&#xff0c;全球智能手机出货量年增长率均超过两位数&#xff0c;显示出强劲的市场需 求和快速扩张趋势。然而&#xff0c;自2016 年起&#xff0c;全球智能手机用户数量趋于饱和&#xff0c;换机周期也逐 渐变长&#xff0c;市场进入存量替换阶段&#x…