Dijikstra算法(堆优化版)

news2024/11/15 23:53:57

当给定数据的范围不大时,采用朴素Dijikstra算法尚能ac,但若是数据范围大于10^5,那么朴素Dijikstra算法就会爆掉,所以我们需要采用堆优化版的Dijikstra算法

堆优化版Dijikstra主要是对朴素Dijikstra中找寻从距离编号 1 结点路径长度最近的结点的过程进行了优化:

朴素Dijikstra算法:

int t = -1;
for (int j = 1;j<= n;++j)
{
    if(!st[j] && ( t == -1 || dist[t] > dist[j]))
        t = j;
}

这段代码的详解请看

http://t.csdnimg.cn/4eT8Z

题目如下:

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

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

输入格式

第一行包含整数 n 和 m。

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

输出格式

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

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

数据范围

1≤n,m≤1.5×10^5

解答代码:

#include<iostream>
#include<cstring>
#include<queue>

using namespace std;

typedef pair<int ,int> pii;//这是队列中的数据类型
                           //{x,y}代表的就是从源节点到编号为 y 的结点的最短路径长是 x 

const int N = 150010;

int n,m;
int e[N],ne[N],h[N],idx,w[N];//用邻接表存储图,因为本题中,结点数的范围和边的范围差不多
                             //本题图的形式是稀疏图,所以用邻接表
                             //邻接表适用于稀疏图,邻接矩阵适用于稠密图
                             //稠密图是边的个数的范围比结点个数的范围要大得多
                             //w[N]用来记录每一条边的边的长度,其中的N是结点的下标
int dist[N];//如dist[i],从编号 1 结点到编号 i 结点的最短路径长度
bool st[N];//如st[i],编号 i 结点是否被确定最短路径


void add(int a,int b,int c)
{
    e[idx] = b;
    w[idx] = c;
    ne[idx]=  h[a];
    h[a] = idx;
    idx++;
}

int dijikstra()
{
    memset(dist,0x3f,sizeof(dist));//还是将dist数组初始值设为无穷大
                                   //即最开始时,任何一个点的最短路径长度都还没确定
                                   //除了dist[1] = 0 ,也就是编号 1 结点到自身的距离为0
    dist[1] = 0;
    
    priority_queue<pii,vector<pii>,greater<pii>> heap;//采用优先队列实现小根堆排序
                                                      //优先队列的本质就是小根堆
    heap.push({0,1});//此时已知从编号 1 结点到编号 1 结点的最短路径长是0
    
    while(heap.size())
    {
        pii t = heap.top();//取出堆顶的元素
                           //优先队列中的所有pair数据的排序默认按照pair中的第一个数据进行排序
                           //优先队列模仿的是小根堆
                           //也就是堆顶的元素永远是此时距离编号 1 结点最近的编号
        heap.pop();//弹出堆顶元素
        
        int ver = t.second;//ver代表堆顶结点的编号
        int distance = t.first;//distance代表从编号 1 结点到堆顶结点的最短路径长度
        
        if(st[ver])//处理遇到重边的情况,画图
        continue;
        
        st[ver] = true;//标记这个点已经找到了最短路径
        
        for (int i = h[ver];i != -1;i = ne[i])//在此时的堆顶结点进行延伸
                                              //此时的 i 是编号 ver 结点的一个子节点的下标
        {
            int j =e[i];//将下标 i 翻译成结点的编号
            
            if (dist[j] > (distance + w[i]))//(1)确定从编号1结点到编号j结点的最短路径长
                                            //(2)处理重边的情况
            {
                dist[j] = distance + w[i];
                heap.push({dist[j],j});//加入队列
                                       //同时依照队列排序的特性,可以处理遇到重边的情况
            }
        }
    }
    
    if  (dist[n] == 0x3f3f3f3f)
    return -1;
    
    else
    return dist[n];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n >> m;
    memset(h,-1,sizeof(h));//照例将存储邻接表的h数组初始值设为-1
                           //代表初始时,图中任何一条边还没有建立
                           
    while(m--)
    {
        int a,b,c;
        cin >> a >> b >>c;
        
        add(a,b,c);
    }
    
    cout << dijikstra()  ;
    return 0;
}

几个问题:

(1)

堆优化版的Dijikstra算法适用于数据范围较大的情况,朴素版的Dijikstra算法适用于数据范围较小的情况

(2)

本题使用邻接表,是因为点的数量 n 和边的数量  m 差不多,是稀疏图,所以用邻接表来存储图

朴素Dijikstra算法中,因为边的数据范围远大于点的数量,是稠密图,所以用邻接矩阵

(3)

 

 

(4) 

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

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

相关文章

突然肾结石了:这时候我才意识到问题

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 中午吃过饭&#xff0c;下腹剧痛&#xff0c;忍了2个小时&#xff0c;我以为是普通肚子痛&#xff0c;因为之前没有任何征兆&#xff0c;所以我忍痛拍了这个视频。 这也是为什么评论区有朋友说&#xff1a;这期视频…

BQ27441初始化配置程序,电压、SOC等参数读取程序

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 前言一、模拟IIC二、BQ27441初始化配置程序三、学习资料 前言 送给大学毕业后找不到奋斗方向的你&#xff08;每周不定…

算法打卡 Day23(二叉树)-二叉搜索树的最小绝对差 + 二叉搜索树中的众数 + 二叉树的最近公共祖先

文章目录 Leetcode 530-二叉搜索树的最小绝对差题目描述解题思路 Leetcode 501-二叉搜索树中的众数题目描述解题思路 Leetcode 236-二叉树的最近公共祖先题目描述解题思路 Leetcode 530-二叉搜索树的最小绝对差 题目描述 https://leetcode.cn/problems/minimum-absolute-diff…

萌啦数据使用多久,萌啦数据价格表2024

在数字化浪潮汹涌的今天&#xff0c;数据已成为企业决策与业务增长的核心驱动力。在众多数据分析工具中&#xff0c;萌啦数据凭借其强大的数据处理能力、直观的数据可视化效果以及灵活的数据分析模型&#xff0c;赢得了众多企业和个人的青睐。那么&#xff0c;关于“萌啦数据使…

C++ | Leetcode C++题解之第341题扁平化嵌套列表迭代器

题目&#xff1a; 题解&#xff1a; class NestedIterator { private:vector<int> vals;vector<int>::iterator cur;void dfs(const vector<NestedInteger> &nestedList) {for (auto &nest : nestedList) {if (nest.isInteger()) {vals.push_back(n…

苍穹外卖项目DAY05

苍穹外卖项目DAY05 1、店铺营业状态设置 1.1、Redis入门 Redis简介 Redis是一个基于内存的key-value结构数据库 基于内存存储&#xff0c;读写性能高适合存储热点数据&#xff08;热点商品、咨询、新闻&#xff09;企业应用广泛 中文网&#xff1a;https://www.redis.net…

FSOP,glibc-2.23攻击IO_list_all

文章目录 FSOP介绍&#xff1a;FOSP链执行流程&#xff1a;源码调试过程 FSOP 介绍&#xff1a; FSOP 是 File Stream Oriented Programming 的缩写&#xff0c;根据前面对 FILE 的介绍得知进程内所有的 _ IO_FILE 结构会使用 _ chain 域相互连接形成一个链表&#xff0c;这个…

景联文科技:一文详解如何构建高质量SFT数据

在图像处理和计算机视觉领域中&#xff0c;将一张图像转化为可用于训练机器学习模型的数据是一项复杂而重要的任务。SFT&#xff08;Supervised Fine-Tuning&#xff0c;监督微调&#xff09;是一种常见的深度学习策略&#xff0c;在这一过程中发挥着核心作用。 SFT是指在一个预…

【云备份】服务端模块-热点管理

文章目录 0.回顾extern1.介绍2.实现思想3.代码测试代码 0.回顾extern extern cloudBackup::DataManager *_dataManager extern 关键字用于声明一个全局变量或对象&#xff0c;而不定义它。这意味着 _dataManager 是一个指向 cloudBackup::DataManager 类型的指针&#xff0c;但…

外部接入tensorboard和Jupyter Notebook

本地端打开服务器端jupyter Notebook 1:服务器端在目标文件夹下输入jupyter notebook --no-browser --port8888&#xff08;留意下token&#xff09; 2&#xff1a;本地端打开git 的bash窗口输入ssh -L 8888:localhost:8888 warren10.12.14.187 warren为用户名&#xff0c;10…

get 请求获取不到参数,但是post参数可以获取到

一&#xff1a;测试代码时发现&#xff0c;get请求一直获取不到参数。最终原因如下&#xff0c;nginx配置中需求有下面的配置 $args&#xff1a;代表接受到的参数

MemFire Cloud是否真的可以取代后端

近年来&#xff0c;随着前端技术的迅速发展&#xff0c;前端工程师们越来越多地开始思考一个问题&#xff1a;“我还能不能不依赖后端&#xff1f;” 这种想法并非空穴来风&#xff0c;尤其是随着像MemFire Cloud这样的工具出现&#xff0c;它不仅能让开发者在没有后端的情况下…

2. springboot集成kafka入门使用教程

项目demo地址 : https://mp.weixin.qq.com/s?__bizMzkzODQyNzE3 1. 项目结构 ─src├─main│ ├─java│ │ └─org│ │ └─example│ │ │ KafkaApplication.java│ │ ││ │ └─demo│ │ KafkaConsume…

跟李沐学AI:目标检测、锚框

边缘框 用于表示物体的位置&#xff0c;一个边缘框通过四个数字定义&#xff1a;(坐上x, 左上y, 右下x, 右下y)或&#xff08;左上x, 左上y, 宽, 高&#xff09; 通常物体检测或目标检测的数据集比图片分类的数据集小很多&#xff0c;因为物体检测数据集标注成本高很多。 目…

音视频相关知识

H.264编码格式 音频 PCM就是要把声音从模拟信号转换成数字信号的一种技术&#xff0c;他的原理简单地说就是利用一个固定的频率对模拟信号进行采样。 pcm是无损音频音频文件格式

【Qt】QWidget的font属性

QWidget的font属性 API说明 font() 获取当前 widget 的字体信息. 返回 QFont 对象. setFont(const QFont& font) 设置当前 widget 的字体信息. 关于Qfont 属性说明 family 字体家族. ⽐如 "楷体", "宋体", "微软雅⿊" 等. pointSiz…

“面试通关秘籍:高频题目与算法整理”

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

Postman断言

目录 概述 断言工作原理 常用断言方法 Status code: Code is 200 Status code: Successful POST request Status code: Code name has string Response body: Contains string Response body: JSON value check Response body: ls equal to a string Response headers…

鸿萌数据恢复服务:SQL Server 中的 GAM、SGAM、IAM,及数据库损坏的修复方法

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份、网络及终端数据安全等解决方案与服务。 同时&#xff0c;鸿萌是国际主流数据恢复软件(Stellar、UFS、R-Studio、ReclaiMe Pro 等)的授权代理商&#xff0c;为专…

开源的数据库增量订阅和消费的中间件——Cancl

目录 工作原理 MySQL主备复制原理 Canal 工作原理 主要功能和特点 应用场景 实验准备 安装JDK11 下载MySQL8.0 配置canal.admin 配置canal-deployer 测试数据读取 新增一台主机用做被同步的目标机器测试 官方地址&#xff1a;https://github.com/alibaba/canal?ta…