DAY64||dijkstra(堆优化版)精讲 ||Bellman_ford 算法精讲
dijkstra(堆优化版)精讲
题目如上题47. 参加科学大会(第六期模拟笔试)
邻接表
本题使用邻接表解决问题。
邻接表的优点:
- 对于稀疏图的存储,只需要存储边,空间利用率高
- 遍历节点链接情况相对容易
缺点:
- 检查任意两个节点间是否存在边,效率相对低,需要 O(V)时间,V表示某节点链接其他节点的数量。
- 实现相对复杂,不易理解
- 节点1 指向 节点3 权值为 1
- 节点1 指向 节点5 权值为 2
- 节点2 指向 节点4 权值为 7
- 节点2 指向 节点3 权值为 6
- 节点2 指向 节点5 权值为 3
- 节点3 指向 节点4 权值为 3
- 节点5 指向 节点1 权值为 10
这样 我们就把图中权值表示出来了。
但是在代码中 使用 pair<int, int>
很容易让我们搞混了,导致代码可读性很差。
那么 可以 定一个类 EDGE来取代 pair<int, int>
堆优化三部曲
1.选源点到哪个节点近且该节点未被访问过,我们需要一个 小顶堆 来帮我们对边的权值排序,每次从小顶堆堆顶 取边就是权值最小的边。
2.该最近节点被标记访问过,和朴素版一样
3.更新非访问节点到源点的距离
和朴素版区别
- 邻接表的表示方式不同
- 使用优先级队列(小顶堆)来对新链接的边排序
代码
堆优化的时间复杂度 只和边的数量有关 和节点数无关,在 优先级队列中 放的也是边。
#include <iostream>
#include <vector>
#include<list>
#include<queue>
#include <climits>
using namespace std;
class mycomparison//小顶堆比较器
{public://重载 () 操作符,比较两个 pair<int, int> 的第二个元素,//返回 lhs.second > rhs.second,使得优先队列按第二个元素从小到大排序。bool operator()(const pair<int,int>&lhs,const pair<int,int>&rhs){return lhs.second>rhs.second;}};
struct Edge
{int to;//邻接顶点int val;//边的权值Edge(int t,int v):to(t),val(v){}//构造函数};int main() {int n,m,p1,p2,val;//公共汽车站数量,公路数量,某站到某站及其所花时间cin>>n>>m;vector<list<Edge>>grid(n+1);//每个元素是一个链表 list<Edge>,用于存储图的邻接表。//读取并填充邻接表for(int i=0;i<m;i++){cin>>p1>>p2>>val;grid[p1].push_back(Edge(p2,val));//将边 p1 到 p2 的信息添加到 grid[p1] 中。}int start=1;int end=n;//初始点和终点vector<int>minDist(n+1,INT_MAX);//存储从起始点到每个节点的最短距离vector<bool>visited(n+1,false);minDist[start]=0;//初始点到自身的距离是0//声明一个优先队列 pq,元素类型为 pair<int, int>,使用 mycomparison 作为比较器,实现小顶堆。priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparison>pg;pg.push(pair<int,int>(start,0));//将起始点及其距离0加入优先队列。//dijkstra算法核心while(!pg.empty()){// <节点, 源点到该节点的距离>// 1、选距离源点最近且未访问过的节点pair<int,int>cur=pg.top();pg.pop();if(visited[cur.first])continue;visited[cur.first]=true;//2.标记该节点已被访问//3.更新非访问节点到源点的距离//遍历当前节点 cur.first 指向的所有邻接节点 edge。for(Edge edge:grid[cur.first]){//如果邻接节点 edge.to 未被访问且通过当前节点 cur.first 到达 edge.to 的距离更短,则更新if(!visited[edge.to]&&minDist[cur.first]+edge.val<minDist[edge.to]){minDist[edge.to]=minDist[cur.first]+edge.val;//将邻接节点 edge.to 及其新的距离加入优先队列。pg.push(pair<int,int>(edge.to,minDist[edge.to]));}}}if(minDist[end]==INT_MAX)cout<<-1<<endl;//无法到达目标elsecout<<minDist[end]<<endl;//到达终点的最短路径}
模拟运行结果
4 4 1 2 1 1 3 4 2 3 1 3 4 1
首先读取
n=4
和m=4
,初始化邻接表grid
。读取边并填充邻接表:
- 边
(1, 2, 1)
,grid[1].push_back(Edge(2, 1))
- 边
(1, 3, 4)
,grid[1].push_back(Edge(3, 4))
- 边
(2, 3, 1)
,grid[2].push_back(Edge(3, 1))
- 边
(3, 4, 1)
,grid[3].push_back(Edge(4, 1))
初始化
minDist
和visited
。初始化优先队列,将起始点及其距离0加入优先队列。
运行 Dijkstra 算法:
- 第一次迭代:从优先队列中取出节点1,更新
minDist
为[0, 1, 4, INT_MAX]
,并将节点2和3加入优先队列。- 第二次迭代:从优先队列中取出节点2,更新
minDist
为[0, 1, 2, INT_MAX]
,并将节点3加入优先队列。- 第三次迭代:从优先队列中取出节点3,更新
minDist
为[0, 1, 2, 3]
,并将节点4加入优先队列。- 第四次迭代:从优先队列中取出节点4,
minDist
保持不变。3
Bellman_ford 算法精讲
94. 城市间货物运输 I
题目描述
某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。
网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。
请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。如果最低运输成本是一个负数,它表示在遵循最优路径的情况下,运输过程中反而能够实现盈利。
城市 1 到城市 n 之间可能会出现没有路径的情况,同时保证道路网络中不存在任何负权回路。
输入描述
第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。
接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v (单向图)。
输出描述
如果能够从城市 1 到连通到城市 n, 请输出一个整数,表示运输成本。如果该整数是负数,则表示实现了盈利。如果从城市 1 没有路径可达城市 n,请输出 "unconnected"。
输入示例
6 7 5 6 -2 1 2 1 5 3 1 2 5 2 2 4 -3 4 6 4 1 3 5
输出示例
1
提示信息
示例中最佳路径是从 1 -> 2 -> 5 -> 6,路上的权值分别为 1 2 -2,最终的最低运输成本为 1 + 2 + (-2) = 1。
示例 2:
4 2
1 2 -1
3 4 -1在此示例中,无法找到一条路径从 1 通往 4,所以此时应该输出 "unconnected"。
数据范围:
1 <= n <= 1000;
1 <= m <= 10000;-100 <= v <= 100;
本题依然是单源最短路问题,求 从 节点1 到节点n 的最小费用。 但本题不同之处在于 边的权值是有负数了。
Bellman_ford算法的核心思想是 对所有边进行松弛n-1次操作(n为节点数量),从而求得目标最短路。
what is 松弛(核心)
例如一条边,节点A 到 节点B 权值为value,如图:
minDist[B] 表示 到达B节点 最小权值,minDist[B] 有哪些状态可以推出来?
状态一: minDist[A] + value 可以推出 minDist[B]
状态二: minDist[B]本身就有权值 (可能是其他边链接的节点B 例如节点C,以至于 minDist[B]记录了其他边到minDist[B]的权值)
minDist[B] 应为如何取舍。
本题我们要求最小权值,那么 这两个状态我们就取最小的
if (minDist[B] > minDist[A] + value) minDist[B] = minDist[A] + value
也就是说,如果 通过 A 到 B 这条边可以获得更短的到达B节点的路径,即如果
minDist[B] > minDist[A] + value
,那么我们就更新minDist[B] = minDist[A] + value
,这个过程就叫做 “松弛” 。Bellman_ford算法 也是采用了动态规划的思想,即:将一个问题分解成多个决策阶段,通过状态之间的递归关系最后计算出全局最优解。
为什么松弛“n-1”次
以上是对所有边进行一次松弛之后的结果。
那么需要对所有边松弛几次才能得到 起点(节点1) 到终点(节点6)的最短距离呢?
对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离。
节点数量为n,那么起点到终点,最多是 n-1 条边相连。
那么无论图是什么样的,边是什么样的顺序,我们对所有边松弛 n-1 次 就一定能得到 起点到达 终点的最短距离。
其实也同时计算出了,起点 到达 所有节点的最短距离,因为所有节点与起点连接的边数最多也就是 n-1 条边。
代码
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main()
{int n,m,p1,p2,val;//节点数、边数、边的两个节点和边的权重。cin>>n>>m;vector<vector<int>>grid;for(int i=0;i<m;i++)//每条边用一个包含三个整数的向量表示。{cin>>p1>>p2>>val;grid.push_back({p1,p2,val});}int start=1;int end=n;vector<int>minDist(n+1,INT_MAX);minDist[start]=0;//Bellman-Ford 算法核心for(int i=1;i<n;i++)//对所有边松弛一次{for(vector<int>&side:grid)//每次松弛,都是对所有边松弛一次{int from=side[0];//边的出发点int to=side[1];//边的到达点int price=side[2];//边的权值//松弛操作//minDist[from] != INT_MAX 防止从未计算过的节点出发if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+price){//且通过当前边到达点的最短距离可以更新,则进行更新minDist[to]=minDist[from]+price;}}}if(minDist[end]==INT_MAX)cout<<"unconnected"<<endl;else cout<<minDist[end]<<endl;//到达终点最短路径}
模拟运行结果
假设输入如下:
4 4 1 2 1 1 3 4 2 3 1 3 4 1
首先读取
n=4
和m=4
,初始化边的存储grid
。读取边并存储在
grid
中:
- 边
(1, 2, 1)
,grid.push_back({1, 2, 1})
- 边
(1, 3, 4)
,grid.push_back({1, 3, 4})
- 边
(2, 3, 1)
,grid.push_back({2, 3, 1})
- 边
(3, 4, 1)
,grid.push_back({3, 4, 1})
初始化
minDist
,设置minDist[start] = 0
。运行 Bellman-Ford 算法:
- 第一次松弛:
- 处理边
(1, 2, 1)
,更新minDist[2] = 1
。- 处理边
(1, 3, 4)
,更新minDist[3] = 4
。- 处理边
(2, 3, 1)
,更新minDist[3] = 2
。- 处理边
(3, 4, 1)
,更新minDist[4] = 3
。- 第二次松弛:
- 处理边
(1, 2, 1)
,minDist[2]
保持不变。- 处理边
(1, 3, 4)
,minDist[3]
保持不变。- 处理边
(2, 3, 1)
,minDist[3]
保持不变。- 处理边
(3, 4, 1)
,minDist[4]
保持不变。- 第三次松弛:
- 处理边
(1, 2, 1)
,minDist[2]
保持不变。- 处理边
(1, 3, 4)
,minDist[3]
保持不变。- 处理边
(2, 3, 1)
,minDist[3]
保持不变。- 处理边
(3, 4, 1)
,minDist[4]
保持不变。最终输出:
3
相关文章:

DAY64||dijkstra(堆优化版)精讲 ||Bellman_ford 算法精讲
dijkstra(堆优化版)精讲 题目如上题47. 参加科学大会(第六期模拟笔试) 邻接表 本题使用邻接表解决问题。 邻接表的优点: 对于稀疏图的存储,只需要存储边,空间利用率高遍历节点链接情况相对容…...

使用Git工具在GitHub的仓库中上传文件夹(超详细)
如何使用Git工具在GitHub的仓库中上传文件夹? 如果觉得博主写的还可以,点赞收藏关注噢~ 第一步:拥有一个本地的仓库 可以fork别人的仓库或者自己新创建 fork别人的仓库 或者自己创建一个仓库 按照要求填写完成后,点击按钮创建…...

Python酷库之旅-第三方库Pandas(218)
目录 一、用法精讲 1021、pandas.DatetimeIndex.inferred_freq属性 1021-1、语法 1021-2、参数 1021-3、功能 1021-4、返回值 1021-5、说明 1021-6、用法 1021-6-1、数据准备 1021-6-2、代码示例 1021-6-3、结果输出 1022、pandas.DatetimeIndex.indexer_at_time方…...
斗鱼大数据面试题及参考答案
MySQL 索引及引擎区别 一、MySQL 索引 索引是一种数据结构,用于快速查找数据库中的数据。它就像是一本书的目录,通过索引可以快速定位到需要的数据行,而不用全表扫描。 普通索引 普通索引是最基本的索引类型,它没有任何限制,可以在一个或多个列上创建。例如,在一个用户表…...
后仿真中的GLS测试用例的选取规则
一 仿真目的 门级仿真的主要目的,从根本上来说,是确保在物理实现阶段所应用的SDC(Standard Delay Constraint,标准延迟约束文件)中的各项约束条件准确无误地反映了设计的初衷和要求。这一环节在芯片设计的整体流程中占据着至关重要的地位,因为它直接关系到最终芯片的物理…...

对接阿里云实人认证
对接阿里云实人认证-身份二要素核验接口整理 目录 应用场景 接口文档 接口信息 请求参数 响应参数 调试 阿里云openApi平台调试 查看调用结果 查看SDK示例 下载SDK 遇到问题 本地调试 总结 应用场景 项目有一个提现的场景,需要用户真实的身份信息。 …...
UI库架构设计
UI库架构设计 分层 rc-xxx,提供基础组件,unstyled component (headless) ,只具备功能交互,不具备UI表现样式体系基础组件复合组件,Search:Input Select ,IconButton:Icon Button业…...

电子应用产品设计方案-9:全自动智能马桶系统设计方案
一、系统概述 本全自动智能马桶系统旨在提供舒适、卫生、便捷和智能化的如厕体验。通过融合多种传感器技术、电子控制单元和机械执行机构,实现马桶的自动冲洗、座圈加热、臀部清洗、烘干等功能,并具备智能感应、用户个性化设置和健康监测等特色功能。 二…...

My_SQL day3
知识点:约束 1.dafault 默认约束 2.not null 非空约束 3.unique key 唯一约束 4.primary key 主键约束 5.anto_increment 自增长约束 6.foreign key 外键约束 知识点:表关系 1.一对一 2.一对多 3.多对多 知识点:约束 1.default 默认约束 …...

【代码随想录day31】【C++复健】56. 合并区间;738.单调递增的数字
56. 合并区间 遇到了三个问题,一一说来: 1 比较应该按左区间排序,我却写了右区间。由于本题是合并区间,判断是否连续显然是用下一个的左区间与前一个的右区间比较,属于没想清楚了。 2 在写for循环时写成了如下的代码…...

jmeter常用配置元件介绍总结之逻辑控制器
系列文章目录 安装jmeter jmeter常用配置元件介绍总结之逻辑控制器 逻辑控制器1.IF控制器2.事务控制器3.循环控制器4.While控制器5.ForEach控制器6.Include控制器7.Runtime控制器8.临界部分控制器9.交替控制器10.仅一次控制器11.简单控制器12.随机控制器13.随机顺序控制器14.吞…...

解决Windows远程桌面 “为安全考虑,已锁定该用户账户,原因是登录尝试或密码更改尝试过多。请稍后片刻再重试,或与系统管理员或技术支持联系“问题
当我们远程连接服务器连接不上并提示“为安全考虑,已锁定该用户账户,原因是登录尝试或密码更改尝试过多。请稍候片刻再重试,或与系统管理员或技术支持联系”时,根本原因是当前计算机远程连接时输入了过多的错误密码,触…...

中文书籍对《人月神话》的引用(161-210本):微软的秘密
中文书籍对《人月神话》的引用(第001到160本)>> 《人月神话》于1975年出版,1995年出二十周年版。自出版以来,该书被大量的书籍和文章引用,直到现在热潮不退。 2023年,清华大学出版社推出《人月神话》…...
关于写React的一些反思和总结
这两个星期我都一直在写IT资产管理这个模块。关于这个模块,前端和后端都是我来处理,对于后端,我碰到了很多问题,但是很多问题都可以在比较短的时间内解决,而且不会说完全没有头绪的那种,这一方面源于我本身…...
Qt 每日面试题 -10
91、Qt设计界面有哪些方式? 手工编写创建界面的代码︰此方法比较复杂,不够直观;使用Qt Designer界面编辑器设计︰可直接拖放控件、设置控件的属性,简单、直观、易于操作;动态加载Ul文件并生成界面︰(QUiLoader类加载xx.ui)此方法很灵活,当需…...
三正科技笔试题
(15题,45分钟,闭卷) 一、( 8 分 )请问以下程序输出什么结果? char *getStr(void) 。 { char p[] "hellow world"; return p; } void test(void) { ch…...

Selective attention improves transformer详细解读
Selective attention improves transformer Google 2024.10.3 一句话:简单且无需额外参数的选择性注意力机制,通过选择性忽略不相关信息并进行上下文剪枝,在不增加计算复杂度的情况下显著提升了Transformer模型的语言建模性能和推理效率。 论…...
git配置用户信息
在 Git 中配置用户信息,主要是设置你的用户名和电子邮件地址,这些信息会被 Git 用来记录提交的作者信息。以下是配置用户信息的步骤: 打开命令行工具。 设置你的用户名: git config --global user.name "你的名字"例如…...

【eNSP】路由基础与路由来源——静态路由实验
路由是数据包从源地址到目的地址的传输路径,静态路由是指网络管理员手动配置的路由条目,用于指定数据包从源地址到目的地址的固定路径。以下是关于静态路由的详细介绍。 一、路由的基础知识点 路由的定义: 路由是指在计算机网络中ÿ…...

Python Web 应用开发基础知识
Python Web 应用开发基础知识 引言 随着互联网的快速发展,Web 应用程序的需求日益增加。Python 作为一种简单易学且功能强大的编程语言,已经成为 Web 开发中广受欢迎的选择之一。本文将深入探讨 Python Web 开发的基础知识,包括常用框架、基…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...