一.算法描述

Dijkstra算法的流程如下:
1.初始化dist[1] = 0,其余节点的dist值为无穷大。
2.找出一个未被标记的、dist[x]最小的节点x,然后标记节点x。
3.扫描节点x的所有出边(x,y,z),若dist[y] > dist[x] + z,则使用dist[x] + z更新dist[y]。
4.重复上述2~3两个步骤,直到所有的节点都被标记。

Dijkstra算法基于贪心思想,它只适用于所有边的长度都是非负整数的图。当边长都是负数时,全局的最小值不可能在被其他节点更新,故在第一步中选出的节点x必然满足:dist[x]已经是起点到x的最短路径。我们不断选择全局最小值进行标记和扩展,最终得到起点1到每个节点的最短路径长度。

二.算法应用

例:对于如下有向图求1 号点到 4 号点的最短距离


(1).初始状态原点到1号的距离为0,因此dist[1] = 0

(2).遍历dist数组找到当前距离原点最近的点i并将该点进行标记,用找到的点i更新i能到的所有点的距离j,如果 dist[j] 大于 dist[i] 加上 i -> j 的距离,即 dist[j] > dist[i] + w[i][j](w[i][j] 为 i -> j 的距离) ,则更新 dist[j] = dist[i] + w[i][j]

(3).重复步骤(2),直到所有的点都被标记为1


三.代码示例

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 510;
int g[N][N], dist[N];
int n, m;
bool st[N];int dijkstra()
{dist[1] = 0;for(int i = 0; i < n; i++){int t = -1;//找到未标记节点中dist最小的for(int j = 1; j <= n; j++)if(!st[j] && (t == -1 || dist[j] < dist[t]))t = j;st[t] = true;//用全局最小的值点t更新其他点for(int j = 1; j <= n; j++)dist[j] = min(dist[j], dist[t] + g[t][j]);}if(dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}int main()
{memset(dist, 0x3f, sizeof dist);//构建邻接矩阵memset(g, 0x3f, sizeof g);cin >> n >> m;for(int i = 0; i < m; i++){int x, y, z;cin >> x >> y >> z;g[x][y] = min(g[x][y], z);}//求单源最短路径dijkstra();for(int i = 1; i <= n; i++) printf("%d\n", dist[i]);return 0;
}

四.算法改进

Dijkstra算法的时间复杂度为O(n^2),主要的瓶颈在于第一步的寻找全局最小值的过程。可以用二叉堆(C++ STL priority_queue)对dist数组进行维护,用O(longn)的时间获取最小值并从堆中删除。用O(longn)的时间执行一条边的扩展和更新,最终可在O(mlongn)的时间内实现Dijkstra算法。

堆优化版的Dijkstra算法

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>#define x first
#define y secondusing namespace std;const int N = 2e5 + 10;typedef pair<int, int> PII;int n, m;
int h[N], e[N], ne[N], w[N], idx; //邻接表
int dist[N];
bool st[N]; //标记数组//构建邻接表
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;//pair的第一维为当前节点到原点的最短距离,第二维为节点编号priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({dist[1], 1});while(heap.size()){//取出堆顶auto k = heap.top();heap.pop();int ver = k.y, distance = k.x;if(st[ver]) continue;st[ver] = true;//扫描所有出边for(int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if(dist[j] > distance + w[i]){//更新,把新的二元组插入堆dist[j] = distance + w[i];heap.push({dist[j], j});}}}if(dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}
int main()
{cin >> n >> m;memset(h, -1, sizeof h);//构建邻接表for(int i = 0; i < m; i++){int a, b, c;cin >> a >> b >> c;add(a, b, c);}cout << dijkstra();return 0;
}
}

Dijkstra算法求最短路相关推荐

  1. 2019中山纪念中学夏令营-Day14 图论初步【dijkstra算法求最短路】

    Dijkstra是我学会的第一个最短路算法,为什么不先去学SPFA呢?因为我在luogu上翻到了一张比较神奇的图: 关于SPFA -它死了 以及网上还有各位大佬的经验告诉我:SPFA这玩意很容易被卡. ...

  2. 【单源最短路】Dijkstra算法求最短路

    题目描述 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值. 请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1. 输入格式 第一 ...

  3. 算法分析与实践-作业2-2使用Dijkstra算法求由顶点a到顶点h的最短路径

    Dijkstra算法求由顶点a到顶点h的最短路径 1.问题 对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径,按实验报告模板编写算法. 2.解析 Dijkstra是一种求单源最短路的算法, ...

  4. _DataStructure_C_Impl:Dijkstra算法求最短路径

    // _DataStructure_C_Impl:Dijkstra #include<stdio.h> #include<stdlib.h> #include<strin ...

  5. POJ 3255(迪杰斯特拉算法求次短路)

    POJ3255,问题是求节点1到n的次短路. 在dijkstra求最短路算法的基础上进行变形,用两个数组分别记录源点到各节点最短路径和次短路径: 每次更新时,都将最短路的节点及可能成为次短路的节点pu ...

  6. Dijkstra算法求最短路径

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. (嗯,第一段是抄的,由 ...

  7. PAT甲级1072 Gas Station (30 分):[C++题解]dijkstra算法、最短路

    文章目录 题目分析 题目来源 题目分析 来源:acwing 分析: 所有的dist[ ]都≤Ds:最小的dist[ ]最大; dist[ ] 总和最大. 由于加油站是字符,为了简单起见,将m个加油站编 ...

  8. Dijkstra算法求单源最短路径

    1.最短路径 在一个连通图中,从一个顶点到另一个顶点间可能存在多条路径,而每条路径的边数并不一定相同.如果是一个带权图,那么路径长度为路径上各边的权值的总和.两个顶点间路径长度最短的那条路径称为两个顶 ...

  9. 标号法(Dijkstra)求最短路 matlab

    Dijkstra算法研究的是从初始点到其他每一节点的最短路径 在求解最短路之前需要将权重矩阵写出,在写的时候需要注意不连通的两个地点要设置成一个无限大的数,在matlab中为inf. 对应的权重矩阵应 ...

最新文章

  1. python整数类型的表示字母_Python学习笔记之基本数据类型-Number
  2. CentOS 6.6编译安装Squid 配置反向代理服务器
  3. Flomaster 2020中文版
  4. 给大家分享一个简单的例子 给SWF加一个壳
  5. shell命令之---sed
  6. java 指针 引用_java中的引用与c中的指针
  7. linux孟庆昌第六章课后题_第六章 参数估计-矩估计:通过课后题理解矩估计
  8. WIN32汇编语言中位图的使用
  9. Onlyoffice安装步骤
  10. 强智教务管理系统爬虫难关1
  11. 88E1111与千兆网口连接
  12. 2018最佳计算机配置,2018年主流的组装电脑配置是什么样的?
  13. 最近邻算法(KNN算法)
  14. Mysql varchar类型长度计算(mysql字段长度计算)
  15. android sqlite delete 返回值,SQLite 使用详解
  16. undefined reference to `std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocat
  17. 图像处理学习笔记之——绪论
  18. 论文参考文献类型代码及书写格式
  19. 从大型电子厂到互联网大厂(富士康到腾讯),我花了1年时间
  20. DELL Inspiron M4010笔记本拆机除尘图解

热门文章

  1. 小米售后投入超1500万 或重蹈谷歌手机失败覆辙
  2. action1c语言,c语言典型例题及代码(1)
  3. 移动机器人计算机视觉就业方向,基于计算机视觉的移动机器人导航
  4. 跑马拉松会遇到哪些突发问题(应对方法)
  5. Java项目:微信小程序商城+后台管理系统(java+SSH+JSP+jQuery+Mysql)
  6. cf #832 Div.2(A-D)
  7. 虚拟同步发电机预同步(无缝切换)matlab/simulink仿真模型
  8. 基于Python的Solidworks二次开发方法
  9. GP TEE中的几种存储方式介绍
  10. 媒体传输协议的演进与未来