算法-图-dijkstra 最短路径

理论知识

dijkstra三部曲

朴素版dijkstra

模拟过程 

堆优化版dijksra

经典模版例题

Dijkstra求最短路 I   

参加科学大会(第六期模拟笔试)--模版题

网络延迟

ref


理论知识

        最短路是图论中的经典问题即:给出一个有向图,一个起点,一个终点,问起点到终点的最短路径。

        dijkstra算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。需要注意两点:

  • dijkstra 算法可以同时求 起点到所有节点的最短路径
  • 权值不能为负数

dijkstra三部曲

  1. 第一步,选源点到哪个节点且该节点未被访问过;(minDist数组里的数值,结合visited数组筛选出未访问的节点)
  2. 第二步,该最近节点被标记访问过;(更新visited数组)
  3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)。minDist数组 用来记录 每一个节点距离源点的最小距离。(更新minDist数组)(初始化的时候就应该初始为最大值

朴素版dijkstra

模拟过程 

        ①初始化:节点0 不做处理,统一从下标1 开始计算,源点(节点1) 到自己的距离为0,所以 minDist[1] = 0; 此时所有节点都没有被访问过,所以 visited数组都为0。

        ②dijkstra 三部曲 :

         

        

      

    

 更新 minDist数组,即:源点(节点1) 到 节点6 、 节点3 和 节点4【与当前被访问节点2相连的节点】的距离。

  • 源点到节点6的最短距离为5,小于原minDist[6]的数值max,更新minDist[6] = 5
  • 源点到节点3的最短距离为3,小于原minDist[3]的数值4,更新minDist[3] = 3
  • 源点到节点4的最短距离为6,小于原minDist[4]的数值max,更新minDist[4] = 6

 

  • 源点到节点4的最短距离为5,小于原minDist[4]的数值6,更新minDist[4] = 5

 

 

...........

...........最终

        节点1)到终点(节点7)的最短距离就是 minDist[7] ,按上面举例讲解来说,minDist[7] = 12,节点1 到节点7的最短路径为 12。 

堆优化版dijksra

        1、邻接表结构存储: vector<vector<pair<int, int>>> adj(n + 1); // 邻接表直接存储边

        2、初始化最  短距离数组和优先队列,设定起点距离

        使用小顶堆(priority_queue)存储 <距离, 节点> 对,初始时将起点 (0, 1) 加入队列

                priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

        3、主循环:通过优先队列快速找到当前最短路径节点,并更新邻接节点。

                

用到的数据结构:

 vector<vector<pair<int, int>>> adj(n + 1)

adj[1] = { {2, 2}, {3, 4} }; // 从 1 出发,有 1→2 (权2),1→3 (权4)
adj[2] = { {3, 1}, {4, 7} }; // 从 2 出发,有 2→3 (权1),2→4 (权7)

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

动态维护当前扩展的最短路径节点

经典模版例题

Dijkstra求最短路 I  

完整代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,m;cin>>n>>m;vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));for(int i=1;i<=m;i++){int x,y,z;cin>>x>>y>>z;if (z < grid[x][y]) {  // 处理重边,保留最小权重grid[x][y] = z;}}vector<int> minDist(n+1,INT_MAX);vector<bool> visited(n+1,false);int start=1;minDist[start]=0;for(int i=1;i<=n;i++){int minval=INT_MAX;int cur=-1;for(int j=1;j<=n;j++){if(!visited[j]&&minDist[j]<minval){minval=minDist[j];cur=j;}}if (cur == -1) break;  // 所有剩余节点不可达visited[cur]=true;for(int j=1;j<=n;j++){if(!visited[j]&&grid[cur][j]!=INT_MAX&&grid[cur][j]+minDist[cur]<minDist[j]){minDist[j]=minDist[cur]+grid[cur][j];}}}if(minDist[n]==INT_MAX) cout<<"-1";else cout<<minDist[n];return 0;
}

注意重边?????!!!!  

堆优化版:

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<pair<int, int>>> adj(n + 1); // 邻接表直接存储边// 读取边并构建邻接表(无需预处理二维数组)for (int i = 0; i < m; ++i) {int x, y, z;cin >> x >> y >> z;adj[x].emplace_back(y, z); // 直接添加所有边}// Dijkstra算法vector<int> dist(n + 1, INT_MAX);priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;dist[1] = 0;pq.push({0, 1});while (!pq.empty()) {auto [d, u] = pq.top();pq.pop();if (d > dist[u]) continue; // 跳过过时记录for (auto [v, w] : adj[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.push({dist[v], v});}}}// 输出结果cout << (dist[n] == INT_MAX ? -1 : dist[n]);return 0;
}

 

参加科学大会(第六期模拟笔试)--模版题

完整代码: (我真的好爱卡哥,代码简洁又易懂!!!!!)

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,m;cin>>n>>m;//邻接矩阵存储vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));//初始化数值为INT_MAXfor(int i=0;i<m;i++) //输入边权{int s,e,v;cin>>s>>e>>v;grid[s][e]=v;//存储边权值}int start=1;//记录源点,从哪个点开始走int end=n;//记录终点vector<int> minDist(n+1,INT_MAX);//存储每个点至源点的最小距离minDist[start]=0;//源点到自身距离为0;vector<bool> visited(n+1,false);//记录该点是否被访问过,初始化都没有被访问过//依次遍历所有结点for(int i=1;i<=n;i++){int minval=INT_MAX;int cur=start;//记录当前被访问的点中哪个点距离源点最近//1、选距离源点最近&&没有被访问过的点for(int v=1;v<=n;v++){if(!visited[v]&&minDist[v]<minval){minval=minDist[v];cur=v;//记录该最近结点的id}}//2、标记该最近结点beifnagwvisited[cur]=true;//3、更新其他非访问节点到源点的距离(更新minDist数组)for(int v=1;v<=n;v++){//没有被访问过的、与 cur相连的、更新后minDist更小的if(!visited[v]&&grid[cur][v]!=INT_MAX &&minDist[v]>minDist[cur]+grid[cur][v])minDist[v]=minDist[cur]+grid[cur][v];}}//不能到达终点if(minDist[end]==INT_MAX) cout<<-1<<endl;else cout<<minDist[end]<<endl; //输出到达终点的最短路径return 0;}

堆优化版:

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m;// 邻接表存储:adj[x]保存从x出发的所有边,格式为<目标节点, 边权>vector<vector<pair<int, int>>> adj(n + 1);// 处理输入并保留最小边权(处理重边)vector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));for (int i = 0; i < m; ++i) {int s, e, v;cin >> s >> e >> v;if (v < grid[s][e]) grid[s][e] = v;  // 仅保留最小权重}// 将邻接矩阵转换为邻接表for (int x = 1; x <= n; ++x) {for (int y = 1; y <= n; ++y) {if (grid[x][y] != INT_MAX) {adj[x].push_back({y, grid[x][y]});}}}// Dijkstra堆优化实现vector<int> dist(n + 1, INT_MAX);        // 存储起点到各节点的最短距离priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; // 小顶堆,格式<距离, 节点>dist[1] = 0;                             // 起点距离初始化为0pq.push({0, 1});                         // 将起点加入堆while (!pq.empty()) {auto [d, u] = pq.top();              // 取出当前距离最小的节点pq.pop();if (d > dist[u]) continue;           // 跳过过时的路径记录for (auto [v, w] : adj[u]) {         // 遍历所有邻接节点if (dist[v] > dist[u] + w) {     // 发现更短路径dist[v] = dist[u] + w;       // 更新距离pq.push({dist[v], v});       // 将新距离加入堆}}}// 输出结果:终点不可达则输出-1cout << (dist[n] == INT_MAX ? -1 : dist[n]) << endl;return 0;
}

 

网络延迟

#include<bits/stdc++.h>
using namespace std;int main() {int n, k, m;cin >> n >> k >> m;vector<vector<int>> grid(n+1, vector<int>(n+1, INT_MAX));for(int i = 0; i < m; ++i) {int u, v, w;cin >> u >> v >> w;grid[u][v] = w; // 存储有向边}vector<int> minDist(n+1, INT_MAX);vector<bool> visited(n+1, false);minDist[k] = 0; // 起点距离为0for(int i = 1; i <= n; ++i) {int minVal = INT_MAX;int cur = -1;// 寻找当前未访问的最小距离节点for(int v = 1; v <= n; ++v) {if (!visited[v] && minDist[v] < minVal) {minVal = minDist[v];cur = v;}}// 所有剩余节点不可达if (cur == -1) break;visited[cur] = true;// 更新相邻节点for(int v = 1; v <= n; ++v) {if (!visited[v] && grid[cur][v] != INT_MAX && minDist[cur] != INT_MAX) {if (minDist[v] > minDist[cur] + grid[cur][v]) {minDist[v] = minDist[cur] + grid[cur][v];}}}}int maxTime = 0;for(int i = 1; i <= n; ++i) {if (minDist[i] == INT_MAX) {cout << -1 << endl;return 0;}maxTime = max(maxTime, minDist[i]);}cout << maxTime << endl;return 0;
}

堆优化版: 

#include <bits/stdc++.h>
using namespace std;int main() {int n, k, m;cin >> n >> k >> m;vector<vector<pair<int, int>>> adj(n + 1); // 邻接表存储图for (int i = 0; i < m; ++i) {int u, v, w;cin >> u >> v >> w;adj[u].emplace_back(v, w);}// Dijkstra算法vector<int> dist(n + 1, INT_MAX);priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;dist[k] = 0;pq.push({0, k});while (!pq.empty()) {auto [d, u] = pq.top();pq.pop();if (d > dist[u]) continue;for (auto [v, w] : adj[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.push({dist[v], v});}}}int maxTime = *max_element(dist.begin() + 1, dist.end());cout << (maxTime == INT_MAX ? -1 : maxTime) << endl;return 0;
}

 

和模版几乎一样,只是最后判断为:所有的minDist不是INT_MAX(均可达),输出是最大的时间(所有举例源点的最短路径中最大的那一个!!!!!!) 好开心~ 

ref

代码随想录

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

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

相关文章

Qt添加MySql数据库驱动

文章目录 一. 安装MySql二.编译mysql动态链接库 Qt版本&#xff1a;5.14.2 MySql版本&#xff1a;8.0.41 一. 安装MySql 参考这里进行安装&#xff1a;https://blog.csdn.net/qq_30150579/article/details/146042922 将mysql安装目录里的bin&#xff0c;include和lib拷贝出来…

浅论数据库聚合:合理使用LambdaQueryWrapper和XML

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算&#xff08;关键优化&#xff09;二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点&#xff1a;使用 XM…

Ubuntu 22.04安装NVIDIA A30显卡驱动

一、安装前准备 1.禁用Nouveau驱动 Ubuntu默认使用开源Nouveau驱动&#xff0c;需要手动禁用&#xff1a; vim /etc/modprobe.d/blacklist-nouveau.conf # 添加以下内容&#xff1a; blacklist nouveau options nouveau modeset0 # 更新内核并重启&#xff1a; update-initr…

Docker Desktop 4.38 安装与配置全流程指南(Windows平台)

一、软件定位与特性 Docker Desktop 是容器化应用开发与部署的一体化工具&#xff0c;支持在本地环境创建、管理和运行Docker容器。4.38版本新增GPU加速支持、WSL 2性能优化和Kubernetes 1.28集群管理功能&#xff0c;适用于微服务开发、CI/CD流水线搭建等场景。 二、安装环境…

音视频入门基础:RTP专题(15)——FFmpeg源码中,获取RTP的视频信息的实现

一、引言 通过FFmpeg命令可以获取到SDP文件描述的RTP流的视频压缩编码格式、色彩格式&#xff08;像素格式&#xff09;、分辨率、帧率信息&#xff1a; ffmpeg -protocol_whitelist "file,rtp,udp" -i XXX.sdp 本文以H.264为例讲述FFmpeg到底是从哪个地方获取到这…

深度学习---卷积神经网络

一、卷积尺寸计算公式 二、池化 池化分为最大池化和平均池化 最常用的就是最大池化&#xff0c;可以认为最大池化不需要引入计算&#xff0c;而平均池化需要引出计算&#xff08;计算平均数&#xff09; 每种池化还分为Pooling和AdaptiveAvgPool Pooling(2)就是每2*2个格子…

netty中Future和ChannelHandler

netty中的Future&#xff0c;继承自 jdk中的Future&#xff0c;&#xff0c; jdk中的Future&#xff0c;很垃圾&#xff0c;只能同步阻塞获取结果&#xff0c;&#xff0c;&#xff0c; netty中的Future进行了升级&#xff0c;&#xff0c;可以addListener()异步获取结果&…

java 初学知识点总结

自己总结着玩 1.基本框架 public class HelloWorld{ public static void main(String[] args){ }//类名用大写字母开头 } 2.输入&#xff1a; (1)Scanner:可读取各种类型&#xff0c;字符串相当于cin>>; Scanner anew Scanner(System.in); Scan…

质量属性场景描述

为了精确描述软件系统的质量属性&#xff0c;通常采用质量属性场景&#xff08;Quality Attribute Scenario&#xff09;作为描述质量属性的手段。质量属性场景是一个具体的质量属性需求&#xff0c;使利益相关者与系统的交互的简短陈述。 质量属性场景是一种用于描述系统如何…

数据可携带权的多重价值与实践思考

文章目录 前言一、数据可携带权的提出与立法二、数据可携带权的多重价值1、推动数据要素市场化配置2、促进市场竞争与创新3、强化个人数据权益 三、数据可携带权的实践挑战1、数据安全与隐私保护面临风险2、接口差异导致数据迁移成本高昂3、可携带的数据范围尚存争议 数据可携带…

蓝桥每日打卡--分考场

#蓝桥#JAVA#分考场 题目描述 n个人参加某项特殊考试。 为了公平&#xff0c;要求任何两个认识的人不能分在同一个考场。 求是少需要分几个考场才能满足条件。 输入描述 输入格式&#xff1a; 第一行&#xff0c;一个整数n(1≤n≤100)&#xff0c;表示参加考试的人数。 …

RMAN备份bug-审计日志暴涨(select action from gv$session)

问题概述 /oracle 文件系统使用率过大&#xff0c;经过检查是审计日志过大,/oracle 目录 197G 审计日志占用70G&#xff0c;每6个小时产生大量审计日志&#xff0c;日志内容全是select action from gv$session &#xff0c;猜测可能跟备份有关&#xff0c; $>df -h /oracle…

在Blender中给SP分纹理组

在Blender中怎么分SP的纹理组/纹理集 其实纹理组就是材质 把同一组的材质分给同一组的模型 导入到sp里面自然就是同一个纹理组 把模型导入SP之后 就自动分好了

Nuxt:Nuxt3框架中onBeforeMount函数 和onBeforeRouteUpdate函数区别介绍 【超详细!】

提示&#xff1a;在 Nuxt3 中&#xff0c;onBeforeMount 和 onBeforeRouteUpdate 是两个不同场景下使用的钩子函数&#xff0c;分别对应 Vue 组件生命周期 和 路由导航守卫。以下是它们的详细解释和对比&#xff1a; 文章目录 一、onBeforeMount&#xff08;Vue 生命周期钩子&a…

华为 Open Gauss 数据库在 Spring Boot 中使用 Flyway

db-migration&#xff1a;Flyway、Liquibase 扩展支持达梦&#xff08;DM&#xff09;、南大通用&#xff08;GBase 8s&#xff09;、OpenGauss 等国产数据库。部分数据库直接支持 Flowable 工作流。 开源代码仓库 Github&#xff1a;https://github.com/mengweijin/db-migrat…

java 查找两个集合的交集部分数据

利用了Java 8的Stream API&#xff0c;代码简洁且效率高 import java.util.stream.Collectors; import java.util.List; import java.util.HashSet; import java.util.Set;public class ListIntersection {public static List<Long> findIntersection(List<Long> …

双足机器狗开发:Rider - Pi

双足机器狗开发:Rider - Pi https://github.com/YahboomTechnology/Rider-Pi-Robot 项目介绍 Rider - Pi是一款为开发者、教育工作者和机器人爱好者设计的桌面双轮腿式机器人,它基于树莓派CM4核心模块构建,具备多种先进功能和特点: 硬件特性 核心模块:采用树莓派CM4核…

Android12 添加开机铃声

系统默认是没有播放开机铃声的功能&#xff0c;MTK有一套自己的开机铃声处理逻辑&#xff0c;代码在/vendor/mediatek/proprietary/operator/frameworks/bootanimation/MtkBootanimation下&#xff0c;但是在10之后MTK就不在维护这部分代码了。直接使用会有很多编译报错&#x…

3.6V-30V宽压输入降压同步IC内置MOS,电流4A/5A/6A,可以满足汽车应急电源,BMS电池,电池组USB口输出等储能应用

今天给大家介绍一下这三款产品&#xff0c;分别是CJ92340,输入电压4.5V-30V&#xff0c;输出可调&#xff0c;电流负载能力可达4A&#xff0c;频率350KHZ。CJ92350,输入电压3.6V-30V&#xff0c;输出可调&#xff0c;频率可调&#xff0c;带载能力达5A。CJ92360,输入电压3.6V-3…

代码随想录算法训练营第35天 | 01背包问题二维、01背包问题一维、416. 分割等和子集

一、01背包问题二维 二维数组&#xff0c;一维为物品&#xff0c;二维为背包重量 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner scanner new Scanner(System.in);int n scanner.nextInt();int bag scanner.nextInt();int[…