Acwing Dijkstra

Dijkstra 算法
在此之前,我们先了解一下整体最短路径的一些解决方法。
在这里插入图片描述

  • 单源最短路,指的是求一个点到其它所有点的最短距离(起点是固定的,单一的)
    • 所有边权都是正数
      • 朴素Dijkstra,基于贪心;
      • 堆优化Dijkstra。当是稀疏图时,堆优化的效果好一点;当是稠密图时,朴素的好一些
  • 多源汇最短路在最短路问题中,源点 也就是 起点汇点 也就是 终点

最短路问题的核心在于,把问题抽象成一个最短路问题,并建图。图论相关的问题,不侧重于算法的原理,侧重于对问题的抽象(也就是写代码出来才是最牛逼的)

1.朴素Dijkstra

主要思想:用一个集合st来存放最短距离已经确定的点。找到1号点到n号点的最短距离,时间复杂度为 O ( n 2 + m ) O(n^2+m) O(n2+m),n表示点数,m表示边数

  1. 初始化距离数组dist[]表示1号点到某点的距离dist[1]=0,dist[i]=0x3f3f3f3f为无穷大;
  2. 循环n次哦:每次从距离已知的点中,选取一个不在st集合中,且距离起点最短的点t(即在未确定最短路径的节点中,寻找距离最小的节点),然后把t加入到集合st[],表示已经确定有最短路径;
  3. 然后遍历一下所有边,用t更新其它点的距离;
  4. 当所有点都被遍历完后,判断dist[n]是否还为无穷大,若是则意味着1和n不连通,否则返回dist[n]即为1号点到n号点的最短路距离

先给出板子:

// 返回从1号点到n号点的最短距离
int dijkstra() {memset(dist, 0x3f, sizeof dist);  // 初始化距离数组为无穷大dist[1] = 0;                      // 1号点到自身的距离为0for (int i = 0; i < n; i++) {//进行 n 次循环,以更新 n 个节点的距离int t = -1;//初始化t 为 -1,表示当前最小距离节点尚未找到。// 在未确定最短路径的节点中,寻找距离最小的节点for (int j = 1; j <= n; j++) {if (!st[j] && (t == -1 || dist[j] < dist[t])) {t = j;}}if (t == -1) break;  // 若未找到可更新的节点,跳出循环st[t] = true;  // 将t加入已确定最短路径的集合// 用t点的距离更新其他节点for (int j = 1; j <= n; j++) {//如果通过节点 t 到达节点 j 的距离更小,则更新 dist[j]。dist[j] = min(dist[j], dist[t] + g[t][j]);}}// 如果不存在1-n的最短路,返回-1if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}

Acwing 849.Dijkstra 求最短路 I
在这里插入图片描述

具体实现代码(详解版):

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 510;int n, m;
int g[N][N];   // 存储每条边
int dist[N];   // 存储1号点到每个点的距离
bool st[N];    // 存储每个点的最短路径是否确定// 返回从1号点到n号点的最短距离
int dijkstra() {memset(dist, 0x3f, sizeof dist);  // 初始化距离数组为无穷大dist[1] = 0;                      // 1号点到自身的距离为0for (int i = 0; i < n; i++) {//进行 n 次循环,以更新 n 个节点的距离int t = -1;//初始化t 为 -1,表示当前最小距离节点尚未找到。// 在未确定最短路径的节点中,寻找距离最小的节点for (int j = 1; j <= n; j++) {if (!st[j] && (t == -1 || dist[j] < dist[t])) {t = j;}}if (t == -1) break;  // 若未找到可更新的节点,跳出循环st[t] = true;  // 将t加入已确定最短路径的集合// 用t点的距离更新其他节点for (int j = 1; j <= n; j++) {//如果通过节点 t 到达节点 j 的距离更小,则更新 dist[j]。dist[j] = min(dist[j], dist[t] + g[t][j]);}}// 如果不存在1-n的最短路,返回-1if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}int main() {cin >> n >> m;// 初始化图,每条边的初始值为无穷大memset(g, 0x3f, sizeof g);while (m--) {int a, b, c;cin >> a >> b >> c;g[a][b] = min(g[a][b], c);  // 更新为最小边权值,防止重边影响}int t = dijkstra();cout << t << endl;return 0;
}

2.堆优化Dijkstra

当图为稀疏图时(点数n和边数m是同一数量级时,如下题),使用堆优化的dijkstra,将时间复杂度由 O ( n 2 ) O(n^2) O(n2)降为 O ( m log ⁡ n ) O(m \log n) O(mlogn)。堆可以自己手写(用数组模拟),也可以使用现成的(C++的STL提供了优先队列priority_queue,即可使用大根堆和根堆,但相比手写堆不提供任意元素修改

在这里插入图片描述
实现思路:堆优化,构造小根堆得到当前未加入点中和起点距离最小的点

  • 稀疏图,采用邻接表存储图,单额外增加一个权值数组w[],代表边a和边b的权值;
  • pair<int,int> PII第一个int表示1号点到该点的距离,第二个int就是该点的编号,利用C++STL优先队列建立小根堆;priority_queue<PII,vector< PII>,greater< PII>> heap;存储当前未加入最短路的点的集合
  • 当堆heap不为空时,取出堆顶元素,即当前未加入中距离起点最近的点,根据该点的出边,更新以该点为中间点后各点与起点的距离是否缩小,若缩小就更新
    • 更新距离时,可能对一些距离已知的点进行更新(更新为更小的距离),按理说,应该修改堆中对应节点的距离值,但由于优先队列中的堆不支持直接修改某元素的值,则可以直接插入一个新的节点(此时对于同一个节点,堆中有两份,即冗余存储),但没有关系,在默认情况下,std::pair 的比较首先比较第一个元素,如果第一个元素相等,再比较第二个元素。因此,如果两个 pair 的第一个 int 值相同,将会比较第二个 int 值谁更小,因此更新距离后堆顶依旧是目前未加入点中和起点距离最小的点。**

具体代码实现(详解版):

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;typedef pair<int, int> PII; // 第一个int是到起点距离,第二个int是当前点的编号
const int N = 150010;int h[N], e[N], ne[N], idx, w[N]; // 构建邻接表
int dist[N];// 存储起点到每个节点的最短距离。
int n, m;
bool st[N]; //存储起点到每个节点的最短距离。// 在a和b之间添加一条边,权值为c
void add(int a, int b, int c) {e[idx] = b;ne[idx] = h[a];w[idx] = c; // 存储边的权值h[a] = idx++;
}int dijkstra() {memset(dist, 0x3f, sizeof dist);dist[1] = 0;// 用优先队列建立小根堆priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1}); // 起点入堆while (heap.size()) {auto t = heap.top(); // 得到堆顶元素,即到起点距离最近的点heap.pop(); // 删除堆顶元素int ver = t.second, distance = t.first; // 得到编号和距离if (st[ver]) continue; // 如果已加入最短路则退出 重新获取堆顶元素st[ver] = true; // 标记加入最短路// 遍历当前节点所连的节点 更新距离for (int i = h[ver]; i != -1; i = ne[i]) {int j = e[i]; // 获得编号dist[j] = min(dist[j],distance + w[i]);heap.push({dist[j],j});//新的距离和节点编号加入优先队列 heap }}return dist[n] == 0x3f3f3f3f ? -1 : dist[n];
}int main() {cin >> n >> m;memset(h, -1, sizeof h); // 初始化链表while (m--) {int a, b, c;cin >> a >> b >> c;add(a, b, c);}int t = dijkstra();cout << t << endl;return 0;
}

以上就是Dijkstra的两种实现方式,当图为稀疏图时(点数n和边数m是同一数量级时,如下题),使用堆优化的dijkstra;稠密图时选择朴素dijkstra

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

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

相关文章

【活动】人工智能时代,程序员如何保持核心竞争力?需要掌握哪些技能?

人工智能时代&#xff0c;程序员如何保持核心竞争力&#xff1f; 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;程序员面临着前所未有的挑战和机遇。AI不仅改变了软件开发的方式&#xff0c;也重新定义了程序员的角色。在这种背景下&#xff0c;如何保持…

15个RPA+GenAI的典型用例

RPA&#xff08;机器人流程自动化&#xff09;和生成式人工智能是数字化转型领域的两种流行工具&#xff1a; 到 2030 年&#xff0c;RPA 的全球市场预计将增长超过 130 亿美元。1.麦肯锡分析的 63 个用例中&#xff0c;预计生成式人工智能每年将增加 2.6 万亿美元 2. 这两种…

C语言长度受限制的字符串函数:(strncpy,strncat,strncmp)

strncpy 重点&#xff1a;1.拷贝num个字符从源字符串到目标空间 2.如果源字符串的长度小于num&#xff0c;则拷贝完源字符串之后&#xff0c;在目标的后边追加0&#xff0c;直到num个 3.这个函数不会拷贝\0。 列子&#xff1a; #include<stdio.h> #include<string…

u-navber自定义导航栏搜索框

效果 代码 <template><view><u-navbar :is-back"false"><view class"navbar"><view class"search"><image src"../../static/my_device/search_icon.png" class"search_image"></i…

三目运算判断字母大小写-C语言

1.问题&#xff1a; 输入一个字符&#xff0c;判别它是否为大写字母&#xff0c;如果是&#xff0c;将它转换成小写&#xff0c;如果不是&#xff0c;不转换。然后输出最后得到的字符&#xff0c;要求使用三目运算符。 2.解答&#xff1a; 用条件表达式来处理&#xff0c;当字…

单域名SSL证书和通配符SSL证书的区别,主要有3点不同

随着互联网的不断发展&#xff0c;网站安全性问题一直备受关注&#xff0c;在保护网站数据安全的过程中&#xff0c;SSL证书一直发挥着至关重要的作用。而在选择SSL证书时&#xff0c;单域名SSL证书和通配符SSL证书是两种常见的选择。本文将详细介绍单域名SSL证书和通配符SSL证…

智源研究院与百度达成战略合作 共建AI产研协同生态

2024年9月24日&#xff0c;北京智源人工智能研究院&#xff08;简称“智源研究院”&#xff09;与北京百度网讯科技有限公司&#xff08;简称“百度”&#xff09;正式签署战略合作协议&#xff0c;双方将充分发挥互补优势&#xff0c;在大模型等领域展开深度合作&#xff0c;共…

《开题报告》基于SpringBoot的交通管理系统的设计与实现+学习文档+答辩讲解视频

开题报告 研究背景 随着城市化进程的加速和机动车保有量的急剧增长&#xff0c;交通管理面临着前所未有的挑战。传统的交通管理方式&#xff0c;如人工监控、纸质记录等&#xff0c;已经难以满足现代交通管理的需求。交通拥堵、违章行为频发、事故处理效率低下等问题日益突出…

柒奶奶火完玖奶奶火,发疯文学号20天涨粉11万!疯狂变现10W+,一文教会你!

今天给大家分享的项目是**AI发疯文学号。**先看一下下面这组图片&#xff0c;点赞都是大几万&#xff0c;一个是柒奶奶另一个是玖奶奶&#xff0c;其实不管是哪个奶奶&#xff0c;都只是发疯文学的载体。 这种账号在小红书涨粉非常快&#xff0c;据说20天就达到了11W&#xff0…

Redis:哨兵机制

在上文主从复制的基础上&#xff0c;如果主节点出现故障该怎么办呢&#xff1f; 在 Redis 主从集群中&#xff0c;哨兵机制是实现主从库自动切换的关键机制&#xff0c;它有效地解决了主从复制模式下故障转移的问题。 哨兵机制&#xff08;Redis Sentinel&#xff09; Redis S…

Linux系统下载各大模型的方法

1. 下载Civitai模型 wget -O xxxx.safetensors "https://civitai.com/api/download/models/xxxx?&tokenxxxxxxxxxx" --content-disposition2. 下载huggingface模型 点击这3个点 选择Clone repository 如果是想下载当前仓库下所有文件&#xff0c;包括好多个GB的…

今年双11哪些东西值得买?分享五款实用耐用的好物,不再乱花钱!

随着一年一度的1111购物节脚步渐近&#xff0c;是否还在为挑选商品而犹豫不决&#xff1f;别担心&#xff0c;我们贴心整理了一份双十一必买好物推荐&#xff0c;专为追求品质生活的您量身打造。跟随这份清单&#xff0c;让您的数字生活更加丰富多彩&#xff0c;无需多虑&#…

自助服务智能终端界面设计,要遵循的7个原则。

自助服务智能终端在银行、医院、政务、公共服务大厅等场景下&#xff0c;为用户提供了诸多方面&#xff0c;因为面对的群体层次不一&#xff0c;所以在设计过程要遵循诸多原则&#xff0c;本文为大家总结了7点。 1. 界面简洁明了&#xff1a; 避免过多的文字和图标&#xff0…

ELK-02-skywalking-v10.0.1安装

文章目录 前言一、下载skywalking二、上传到服务器并解压三、安装jdk21四、修改配置五、启动总结 前言 skywalking-v10.0.1安装。 运用es持久化数据&#xff0c;所以需先完成ELK-01步骤。 一、下载skywalking 下载地址&#xff1a;https://skywalking.apache.org/downloads/ …

python-list

Python 列表 原文:https://www.geeksforgeeks.org/python-list/ 列表就像动态大小的数组&#xff0c;用其他语言声明(C中的 vector 和 Java 中的 ArrayList)。列表不必总是相同的&#xff0c;这使得它成为 Python 中最强大的工具。单个列表可能包含整数、字符串和对象等数据类型…

指针 (2)

目录 1.指针变量的⼤⼩ 2 指针的解引⽤ 3指针-整数 1.指针变量的⼤⼩ 指针变量的大小和编译器的位数有关系&#xff0c;例如vs2022的 x64 就是64位&#xff0c; x86 就是 32位 当两个同时运行一个代码的时候就会有差异。 当我在运行x86的时 总结&#xff1a; 在x86…

java面对对象高级

1.类变量和类方法 1.1static变量 &#xff08;1&#xff09;类变量&#xff1a; 也叫静态变量/静态属性&#xff0c;所有对象共享并且所有对象访问的值是相同的 static变量是同一个类所有对象共享的 static类变量&#xff0c;在类加载的时候就生成了 &#xff08;2&#xff09…

MySQL基础篇 - SQL

01 SQL通用语法 02 SQL分类 03 DDL语句 04 DML语句 05 DQL语句(单表查询) 05_01 学习总览 05_02 基本查询 05_03 条件查询 【应用实例】&#xff1a; 05_04 聚合函数 05_05 分组查询 05_06 排序查询 05_07 分页查询 【boss题目】&#xff1a; 05_08 执行顺序 06 DCL语句 【概…

国家标准和团体标准有什么区别?

国家标准和团体标准的区别主要体现在以下几个方面&#xff1a; 1. 制定标准的主体不同&#xff1a;国家标准是由国家机构通过并公开发布的标准&#xff1b;团体标准是由学会、协会、商会、联合会、产业技术联盟等社会团体协调相关市场主体共同制…

Libtorrent 安装、编译与使用(附 Boost 的编译与使用)

文章目录 Part.I IntroductionChap.I 预备知识Chap.II 所用设备系统与软件Part.II 准备工作Chap.I 编译 Boost 库Chap.II 下载必需文件Part.III 编译与使用 LibtorrentChap.I 运行 Example 和 TestChap.II 使用库文件ReferencePart.I Introduction libtorrent 是 BitTorrent 协…