当前位置: 首页 > news >正文

代码随想录算法训练营第五十九天 | dijkstra(堆优化版)精讲

目录

dijkstra(堆优化版)精讲

思路

堆优化细节

方法一: 最小堆优化


dijkstra(堆优化版)精讲

  • 题目链接:卡码网:47. 参加科学大会
  • 文章讲解:代码随想录 

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。

小明的起点是第一个车站,终点是最后一个车站。然而,途中的各个车站之间的道路状况、交通拥堵程度以及可能的自然因素(如天气变化)等不同,这些因素都会影响每条路径的通行时间。

小明希望能选择一条花费时间最少的路线,以确保他能够尽快到达目的地。

【输入描述】

第一行包含两个正整数,第一个正整数 N 表示一共有 N 个公共汽车站,第二个正整数 M 表示有 M 条公路。

接下来为 M 行,每行包括三个整数,S、E 和 V,代表了从 S 车站可以单向直达 E 车站,并且需要花费 V 单位的时间。

【输出描述】

输出一个整数,代表小明从起点到终点所花费的最小时间。

输入示例

7 9
1 2 1
1 3 4
2 3 2
2 4 5
3 4 2
4 5 3
2 6 4
5 7 4
6 7 9

输出示例:12

【提示信息】

能够到达的情况:

如下图所示,起始车站为 1 号车站,终点车站为 7 号车站,绿色路线为最短的路线,路线总长度为 12,则输出 12。

不能到达的情况:

如下图所示,当从起始车站不能到达终点车站时,则输出 -1。

数据范围:

1 <= N <= 500; 1 <= M <= 5000

思路

堆优化细节

其实思路依然是 dijkstra 三部曲:

  1. 第一步,选源点到哪个节点近且该节点未被访问过
  2. 第二步,该最近节点被标记访问过
  3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)

只不过之前是 通过遍历节点来遍历边,通过两层for循环来寻找距离源点最近节点。 这次我们直接遍历边,且通过堆来对边进行排序,达到直接选择距离源点最近节点。

先来看一下针对这三部曲,如果用 堆来优化。

那么三部曲中的第一步(选源点到哪个节点近且该节点未被访问过),我们如何选?

我们要选择距离源点近的节点(即:该边的权值最小),所以 我们需要一个 小顶堆 来帮我们对边的权值排序,每次从小顶堆堆顶 取边就是权值最小的边。

pq中中为什么要存 源点到该节点的权值,因为 这个小顶堆需要按照权值来排序)

有了小顶堆自动对边的权值排序,那我们只需要直接从 堆里取堆顶元素(小顶堆中,最小的权值在上面),就可以取到离源点最近的节点了 (未访问过的节点,不会加到堆里进行排序)

所以三部曲中的第一步,我们不用 for循环去遍历,直接取堆顶元素:

# 1. 第一步,选源点到哪个节点近且该节点未被访问过 (通过优先级队列来实现)
# 节点, 源点到该节点的距离
cur_dict,cur_node = heapq.heappop(pq)

第二步(该最近节点被标记访问过) 这个就是将 节点做访问标记,和 朴素dijkstra 一样 ,代码如下:

# 2. 第二步,该最近节点被标记访问过
visited[cur_node] = True

cur.first 是指取 pair<int, int> 里的第一个int,即节点编号 )

第三步(更新非访问节点到源点的距离),这里的思路 也是 和朴素dijkstra一样的。

但很多录友对这里是最懵的,主要是因为两点:

  • 没有理解透彻 dijkstra 的思路
  • 没有理解 邻接表的表达方式

我们来回顾一下 朴素dijkstra 在这一步的代码和思路(如果没看过我讲解的朴素版dijkstra,这里会看不懂)

# 3、第三步,更新非访问节点到源点的距离(即更新minDist数组)
for j in range(1,n+1):if not visited[j] and graph[cur][j] != float('inf') and graph[cur][j] + minDist[cur] < minDist[j]:minDist[j] = minDist[cur] + graph[cur][j]

其中 for循环是用来做什么的? 是为了 找到 节点cur 链接指向了哪些节点,因为使用邻接矩阵的表达方式 所以把所有节点遍历一遍。

而在邻接表中,我们可以以相对高效的方式知道一个节点链接指向哪些节点。

所以在邻接表中,我们要获取 节点cur 链接指向哪些节点,就是遍历 graph[cur节点编号] 这个链表。

接下来就是更新 非访问节点到源点的距离,代码实现和 朴素dijkstra 是一样的,代码如下:

for edge in edges[cur_node]:if not visited[edge.to] and cur_dict + edge.val < minDist[edge.to]:minDist[edge.to] = cur_dict + edge.valheapq.heappush(pq,(minDist[edge.to],edge.to))

方法一: 最小堆优化

import heapq
import sys
class Edge:def __init__(self,to,val) -> None:self.to = to self.val = valdef dijkstra(edges,n,start,end):visited = [False] * (n+1)minDist = [float('inf')] * (n+1)minDist[start] = 0pq = []heapq.heappush(pq,(0,start))while pq:cur_dict,cur_node = heapq.heappop(pq)if visited[cur_node]:continuevisited[cur_node] = Truefor edge in edges[cur_node]:if not visited[edge.to] and cur_dict + edge.val < minDist[edge.to]:minDist[edge.to] = cur_dict + edge.valheapq.heappush(pq,(minDist[edge.to],edge.to))return -1 if minDist[end] == float('inf') else minDist[end]
if __name__=="__main__":input = sys.stdin.readdata = input().split()# n个车站,m条公路n = int(data[0])m = int(data[1])edges = [[] for i in range(n+1)]index = 2for i in range(m):start = int(data[index])to = int(data[index+1])val = int(data[index+2])edges[start].append(Edge(to,val))index += 3res = dijkstra(edges,n,start=1,end=n)print(res)

相关文章:

代码随想录算法训练营第五十九天 | dijkstra(堆优化版)精讲

目录 dijkstra&#xff08;堆优化版&#xff09;精讲 思路 堆优化细节 方法一&#xff1a; 最小堆优化 dijkstra&#xff08;堆优化版&#xff09;精讲 题目链接&#xff1a;卡码网&#xff1a;47. 参加科学大会 文章讲解&#xff1a;代码随想录 小明是一位科学家&#x…...

go语言后端开发学习(七)——如何在gin框架中集成限流中间件

一.什么是限流 限流又称为流量控制&#xff08;流控&#xff09;&#xff0c;通常是指限制到达系统的并发请求数。 我们生活中也会经常遇到限流的场景&#xff0c;比如&#xff1a;某景区限制每日进入景区的游客数量为8万人&#xff1b;沙河地铁站早高峰通过站外排队逐一放行的…...

SpringBoot2:web开发常用功能实现及原理解析-整合EasyExcel实现Excel导入导出功能

1、工程包结构 主要是这5个Java类 2、导入EasyExcel包 这里同时贴出其他相关springboot的基础包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><depend…...

CTFShow-信息搜集

Web1&#xff1a; ​ 题目描述&#xff1a;开发注释未及时删除 。 ​ 打开题目后提示web1:where is flag? ​ ctrlu读取源码。 Web2&#xff1a; ​ 题目描述&#xff1a;js前台拦截 无效操作 ​ 打开题目后显示&#xff1a;无法查看源代码 ​ 右键无法用&#xff0c;…...

Facebook的虚拟现实功能简介:社交网络的新前沿

在科技飞速发展的今天&#xff0c;虚拟现实&#xff08;VR&#xff09;已经从科幻小说中的梦想变成了触手可及的现实。作为全球领先的社交平台&#xff0c;Facebook&#xff08;现已更名为Meta&#xff09;正大力推动虚拟现实技术的发展&#xff0c;以重新定义用户的社交体验。…...

Redis embstr 编码

embstr 编码 是 Redis 中一种优化存储小型字符串的编码方式。它是 Redis 内部存储字符串的多种方式之一&#xff0c;特别适用于存储长度不超过 44 字节的小字符串。...

【Elasticsearch系列二】安装 Kibana

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

中国电子学会202403青少年软件编程(Python)等级考试试卷(三级)真题与解析

202403Python 三级真题 一、选择题 1.在 Python 中,hex(2023)的功能是?( ) A.将十进制数 2023 转化为十六进制数 B.将十进制数 2023 转化为八进制数 C.将十六进制数 2023 转化为十进制数 D.将八进制数 2023 转化为十进制数 2.下列表达式的值与其他三个选项不相…...

k8s 资源管理

文章目录 ResourceQuota什么是资源配额定义一个ResourceQuotaResourceQuota的使用 LimitRangeLimitRange的用途示例1&#xff1a;配置默认的requests和limits示例2&#xff1a;配置requests和limits的范围 QoS什么是服务质量保证示例1&#xff1a;实现QoS为Guaranteed的Pod示例…...

演示:基于WPF的自绘的中国地铁轨道控件

一、目的&#xff1a;演示一个基于WPF的自绘的中国地铁轨道控件 二、效果演示 北京地铁 成都地铁 上海地铁 深圳地铁 南京地铁 长春地铁 哈尔滨地铁 武汉地铁 厦门地铁 香港地铁 三、功能 支持平移、缩放等操作 鼠标悬停显示线路信息和站点信息 按表格显示&#xff0c;按纸张…...

设计模式(Design Patterns)

设计模式&#xff08;Design Patterns&#xff09;是软件开发人员在软件设计过程中面临的一般性问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。设计模式的目的是为了提高代码的可重用性、可维护性、可读性、可靠性以及灵活性。设…...

C++:opencv生成结构元素用于膨胀腐蚀等cv::getStructuringElement

cv::getStructuringElement 是 OpenCV 库中用于生成结构元素的函数。结构元素在形态学操作中&#xff08;如膨胀、腐蚀、开运算、闭运算等&#xff09;扮演着关键角色。这个函数可以创建不同形状和尺寸的结构元素&#xff0c;以适应不同的图像处理需求。 函数原型 cv::Mat cv…...

最大余额法,解决百分比计算相加不等于100%(扇形/饼图百分比使用的此算法)

在开发项目的过程中有时候需要进行计算百分比&#xff0c;例如计算饼状图百分比。有时候在计算的过程中常规四舍五入计算会发生所有计算的值相加不等于100%的情况 这是 get_percent_value 函数的 JavaScript 版本&#xff1a; /*** 最大余额法&#xff0c;解决百分比计算相加不…...

哈希表简单介绍

概念 在顺序结构以及平衡树中&#xff0c;元素关键字与他们存储的位置并没有直接的映射关系&#xff0c;从而会影响查找关键字的效率&#xff0c;顺序结构中查找关键字的时间复杂度为O&#xff08;N&#xff09;&#xff0c;平衡树查找关键字的时间复杂度为O&#xff08;log2^…...

kafka 之 本地部署单机版

安装JDK 查看你选择的版本需要安装哪一个版本的jdk 网址 下载 JDK下载 注&#xff1a;如果网页不允许下载&#xff0c;使用wget命令下载即可&#xff0c;下载之后安装。 建议使用rpm安装&#xff0c;之后使用 update-alternatives --config java 控制当前环境使用Java的版…...

开发一款通过蓝牙连接控制水电表的微信小程序

增强软硬件交互 为了更好的解决师生生活中的实际问题&#xff0c;开发蓝牙小程序加强了和校区硬件的交互。 比如通过蓝牙连接控制水电表&#xff0c;减少实体卡片的使用。添加人脸活体检测功能&#xff0c;提高本人认证效率&#xff0c;减少师生等待时间。 蓝牙水电控展示 蓝…...

力扣14.最长公共前缀

思路&#xff1a;将字符串数组中第一个字符串用作参考&#xff1b; 8.将他的长度作为范围&#xff0c;因为超范围了之后就不会再有公共前缀了 9.将字符串数组的长度也作为范围&#xff0c;意思是便利字符串数组中的字符串 11.开始第一层循环&#xff0c;依次遍历第一个字符串的…...

你也喜欢“钓鱼“吗?

免责声明:本文仅做分享! 目录 什么是网络钓鱼 流程 攻击手法 0-隐藏自己 1-office宏 创建xxx.dotm 创建xxx.docx 2-RLO 自解压 3-快捷方式lnk 4-邮件伪造 Swaks Gophish 5-网站克隆 setoolkit nginx反向代理 前端页面克隆 6-wifi钓鱼 7-其他 防御 溯源 反…...

druid jdbc 执行 sql 输出 开销耗时

druid 执行sql输出 参考链接配置_LogFilter alibaba/druid Wiki GitHub 看不太懂的往这里瞅瞅。 1. 别名映射 这个地方 给我们提供了 5 种 logfilter : log4j、log4j2、slf4j、commonlogging和commonLogging 每一种实际上都代表一个日志框架 或 日志门面。 -Ddruid.fil…...

C++如何处理内存碎片问题

目录 一.前言二.什么是内存碎片三.如何处理内存碎片 一.前言 这篇文章简单讨论一下C如何处理内存碎片问题。 二.什么是内存碎片 所谓内存碎片就是系统中存在的不能供进程使用的小块内存&#xff0c;主要包括外部碎片以及内部碎片。 外部碎片&#xff1a;内存分配和回收的过…...

Kubernetes部署Valheim游戏服务器:云原生技术赋能游戏运维实践

1. 项目概述&#xff1a;当维京英灵殿遇上容器编排如果你和我一样&#xff0c;既沉迷于《英灵神殿》&#xff08;Valheim&#xff09;里与好友共建家园、挑战上古巨兽的乐趣&#xff0c;又恰好是一名整天和Kubernetes&#xff08;k8s&#xff09;打交道的开发者或运维&#xff…...

Legacy-iOS-Kit完整指南:如何让老旧iPhone和iPad重获新生

Legacy-iOS-Kit完整指南&#xff1a;如何让老旧iPhone和iPad重获新生 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …...

gwadd:轻量级Git仓库组管理工具,提升多项目开发效率

1. 项目概述&#xff1a;一个被低估的Git仓库管理利器如果你和我一样&#xff0c;日常工作中需要频繁地在多个Git仓库之间穿梭&#xff0c;处理各种依赖、子模块&#xff0c;或者仅仅是同步一堆相关的项目代码&#xff0c;那么你一定对那种重复、繁琐的切换和操作感到头疼。今天…...

基于xclaude-plugin框架的Claude自定义插件开发实战指南

1. 项目概述&#xff1a;Claude插件生态的“瑞士军刀”如果你最近在深度使用Claude&#xff0c;尤其是Claude Desktop应用&#xff0c;那你大概率已经感受到了插件生态的潜力与混乱。官方插件商店虽然方便&#xff0c;但总有些特定需求找不到现成的解决方案&#xff0c;或者找到…...

C语言结构体:从‘学生信息管理‘到‘链表实现‘的保姆级跃迁指南(含typedef避坑)

C语言结构体&#xff1a;从学生信息管理到链表实现的实战进阶 在C语言的世界里&#xff0c;结构体就像是一个神奇的收纳盒&#xff0c;它能够将不同类型的数据打包成一个整体。想象一下&#xff0c;当你需要管理学生信息时&#xff0c;不再需要为姓名、学号、成绩等分别定义变量…...

大语言模型并行推理技术Hogwild! Inference解析

1. 大语言模型并行推理的技术挑战在传统的大语言模型推理过程中&#xff0c;文本生成采用的是严格的自回归方式&#xff0c;即每个token的生成都依赖于之前所有token的输出。这种串行模式虽然保证了生成的连贯性&#xff0c;但也带来了显著的性能瓶颈。以1750亿参数的GPT-3为例…...

FTDI Friend:从USB转串口到AVR编程的嵌入式开发利器

1. 项目概述&#xff1a;为什么你需要一个FTDI Friend&#xff1f;在嵌入式开发和单片机玩家里&#xff0c;串口通信就像空气和水一样基础且不可或缺。无论是给Arduino上传代码&#xff0c;还是让树莓派和传感器模块“说上话”&#xff0c;亦或是调试一个自己焊的STM32最小系统…...

暗黑破坏神II终极角色编辑器:Diablo Edit2完全使用指南

暗黑破坏神II终极角色编辑器&#xff1a;Diablo Edit2完全使用指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit Diablo Edit2是暗黑破坏神II玩家必备的角色存档编辑器&#xff0c;这款开源工具…...

【PCL中Ptr释放问题 aligned_free 的2种解决方法】

PCL中Ptr释放问题 aligned_free解决方法1解决方法2解决方法1 添加avx指令&#xff0c;参考这篇博客https://blog.csdn.net/qq_60609496/article/details/123900817 解决方法2 我按照方法1尝试添加了avx或者sse等&#xff0c;都不行&#xff0c;我是要做一个静态库的时候链接…...

用1.44寸ST7735 TFT屏DIY一个桌面天气站(附STM32/Arduino完整项目代码)

用1.44寸ST7735 TFT屏打造智能桌面天气站&#xff08;STM32/Arduino全流程实战&#xff09; 在创客圈里&#xff0c;能够实时显示天气信息的桌面小设备一直备受青睐。本文将带你从零开始&#xff0c;利用常见的1.44寸ST7735 TFT屏幕&#xff0c;构建一个功能完善的智能天气站。…...