南昌理工acm集训队


迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959年提出的,是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。

基本思想

Dijkstra算法是用来解决不含负边的最短路问题,其在运行过程中维持的关键信息是一组节点集合S。算法重复从结点集V-S中选择最短路径估计最小的结点u,将u加入到集合S,然后对所有从u发生的边进行松弛,运行结束后,从源节点到集合S中每个结点之间的最短路径已经被找到。

图解

如图,是一个有向无环图,假定出发点为V1,迪杰斯特拉算法将算出V1到其他所有点的最短路径,则所求V1到终点的最短路径也可得到,该算法主要完成以下几步:

1.找到v1

2.得到以V1出发的邻接点的最短距离,将V1加到S集合中(代码中以dist数组呈现)

3.从S集合之外的点中找到距离最短者,对以其为出发点的邻接点进行松弛操作,若距离被更新,则记录前驱

4.重复3直到集合S存满

完成后,将得到V1到所有点的最短距离,同时,通过每一个点记录的前驱得到最短路径。

如何用堆来优化Dijkstra算法?

首先,我们可以用邻接链表来存储图

代码如下:

const int N = 150010;int w[N]; //存边的权值
int e[N], ne[N], h[N], idx;void add(int a, int b, int c)
{w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

我们可以用pair来储存当前的距离和所对应的点,再用小根堆存储pair,这里我们要特别注意以下,pair排序时是先根据first,再根据second,所以first储存距离,second储存当前的点。

代码如下:

typedef pair<int, int> PII;prority_queue<PII, vector<PII>, greater<PII>> heap; //定义小根堆
heap.push({0, 1}); //假设起点是1

时间复杂度分析

寻找路径最短的点:O(n)

加入集合S:O(n)

更新距离:O(mlogn)

完整代码:

#include<iostream>
#include<cstring>
#include<queue>using namespace std;typedef pair<int, int> PII;const int N = 100010; // 把N改为150010就能ac// 稀疏图用邻接表来存
int h[N], e[N], ne[N], idx;
int w[N]; // 用来存权重
int dist[N];
bool st[N]; // 如果为true说明这个点的最短路径已经确定int n, m;void add(int a, int b, int c)
{w[idx] = c; // 有重边也不要紧,假设1->2有权重为2和3的边,再遍历到点1的时候2号点的距离会更新两次放入堆中e[idx] = b; // 这样堆中会有很多冗余的点,但是在弹出的时候还是会弹出最小值2+a(a为之前确定的最短路径),并ne[idx] = h[a]; // 标记st为true,所以下一次弹出3+a会continue不会向下执行。h[a] = idx++;
}int dijkstra()
{memset(dist, 0x3f, sizeof(dist));dist[0] = 1;priority_queue<PII, vector<PII>, greater<PII>> heap; // 定义一个小根堆// 这里heap中为什么要存pair呢,首先小根堆是根据距离来排的,所以有一个变量要是距离,其次在从堆中拿出来的时    // 候要知道知道这个点是哪个点,不然怎么更新邻接点呢?所以第二个变量要存点。heap.push({ 0, 1 }); // 这个顺序不能倒,pair排序时是先根据first,再根据second,这里显然要根据距离排序while(heap.size()){PII k = heap.top(); // 取不在集合S中距离最短的点heap.pop();int ver = k.second, distance = k.first;if(st[ver]) continue;st[ver] = true;for(int i = h[ver]; i != -1; i = ne[i]){int j = e[i]; // i只是个下标,e中在存的是i这个下标对应的点。if(dist[j] > distance + w[i]){dist[j] = distance + w[i];heap.push({ dist[j], j });}}}if(dist[n] == 0x3f3f3f3f) return -1;else return dist[n];
}int main()
{memset(h, -1, sizeof(h));scanf("%d%d", &n, &m);while (m--){int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}cout << dijkstra() << endl;return 0;
}
/*
代码作者:optimjie
来源:AcWing
*/

题目链接:850. Dijkstra求最短路 II - AcWing题库

Dijkstra算法(堆优化版求稀疏图最短路)相关推荐

  1. PAT甲级1003 Emergency Dijkstra算法(堆优化版/朴素版)

    前言   最近花了很多的时间在写JAVA项目上面,疏忽了算法和数据结构的学习.最近突然醒悟基础更为重要,打算从今天开始每天抽出一些时间做下PAT甲级的题目.现有题库的前两题很简单,从第三题开始吧. 题 ...

  2. 牛客 刺客信条 (bfs、dijkstra)+堆优化、dfs三种求解

    最短路 BFS+优先队列 DFS dijkstra+堆优化 题目描述 万物皆虚,万事皆允,玩过刺客信条的人对这句话应该都不会感到陌生 小A也是非常痴迷于这款游戏,正巧最近<刺客信条·奥德赛> ...

  3. 堆优化版dijkstra算法:AcWing 850. Dijkstra求最短路 II

    堆优化版dijkstra算法分析: 朴素版dijkstra的时间复杂度为O(n^2),主要瓶颈在于第1步的寻找全局最小值的过程. 可以用小根堆(C++STL priority_queue)对dist数 ...

  4. 堆优化版迪杰斯特拉(Dijkstra)算法简单分析

    堆优化版迪杰斯特拉算法: 优化原理: 上面的朴素版迪杰斯特拉算法主要缺陷是,每当找到一个最短路径,如果需要找下一个最短路径,就需要在完成松弛操作之后,遍历dist数组,寻找其中的最小值.遍历dist数 ...

  5. AcWing 850. Dijkstra求最短路 II【最短路】【堆优化版Dijkstra】

    AcWing 850. Dijkstra求最短路 II 一.题目链接 二.题目分析 (一)算法标签 (二)解题思路 三.AC代码 四.其它题解 一.题目链接 AcWing 850. Dijkstra求 ...

  6. 迪杰斯特拉算法(dijkstra)_朴素版_堆优化版

    文章目录 Dijkstra算法 ①朴素版(适用于稠密图) 具体实现 ②堆优化版 具体实现 Dijkstra算法 适用于单源最短路且边权都为正数 例:输入有向图/无向图,输出n号点到1号点的最短距离 ① ...

  7. c++ 堆优化版dijkstra 代码实现

    dijkstra是图论中解决最短路问题的重要算法之一,必须熟练掌握 dijkstra用于解决单源最短路问题,要求图中必须不存在负边权 朴素dijkstra的时间复杂度为O(n^2),堆优化版dijks ...

  8. dij算法堆优化_迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少

    算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即:U ={其余顶点},若v与U中顶点u有边,则(u,v)为正常权值,若u不是v的出边邻接点,则(u, ...

  9. dij算法堆优化_迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少(示例代码)...

    算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即:U ={其余顶点},若v与U中顶点u有边,则(u,v)为正常权值,若u不是v的出边邻接点,则(u, ...

最新文章

  1. 利用 Python 打造一个语音合成系统
  2. php顺序、二分查找
  3. 为什么下拉框拉不下来_太气人了!《除暴》吴彦祖的浴巾为什么就是掉不下来?...
  4. 【 D3.js 入门系列 --- 9 】 常见可视化图形
  5. redis学习之——redis.conf配置(基本)文件学习
  6. 金山网络CEO傅盛:简约之美
  7. python自动化常见面试题_Python基础面试题80问 Python自动化开发
  8. android 第三方裁剪,Android裁剪意向不适用于系统图库应用程序,但适用于第三方应用程序...
  9. React-组件生命周期
  10. csrf防御 php,跨站请求伪造CSRF的防御实例(PHP版本)
  11. Python类中的__init__,__del__和__call__方法
  12. draw什么计算机软件,[计算机软件及应用]化学绘图软件ChemDraw使用简介.ppt
  13. OLED屏显和汉字点阵编码原理
  14. 高分七号卫星发射成功
  15. 【实用工具】treer生成项目的目录结构,帮助大家书写好的项目readme
  16. 矩阵计算在计算机科学中,开发者必读:计算机科学中的线性代数
  17. 用ArcGIS Server服务Print打印高清大图的关键参数
  18. CV-提取图像Freeman码python实现
  19. 君が呼ぶ、メギドの丘で スキルライン
  20. 一元域名-真实的谎言

热门文章

  1. mysql group by 和 having 用法
  2. Node.js | 使用 zlib 内置模块进行 gzip 压缩
  3. C++——多态|虚函数|重写|虚表
  4. 牛吃草问题,若放养27头牛,6天把草吃完 ; 若放养23头牛,9天把草吃完。若放养21头牛,几天能把草吃完?(所有数据均用变量输入)
  5. 计算机游戏性能测评,总结:游戏性能属均衡_联想 IdeaCentre B325-劲速型_一体电脑评测-中关村在线...
  6. CentOS LiveCD LiveDVD DVD 等版本的区别 以及 最新版7.1下载
  7. VUE3 获取元素高度
  8. Django数据库缓存
  9. 再有谁说不熟悉 Zabbix 监控系统,就把这个给他扔过去!
  10. vue组件 - 封装使用