Dijkstra算法基于贪心,分为朴素版和堆优化版,稠密图用朴素版,稀疏图用堆优化版。

算法思想

首先给定起始点和终点,求起始点到终点的最短路径。
Dijkstra算法的做法是:

  1. 在所有顶点里找到距离起点最近的点,将它放入集合S。
  2. 用这个顶点来更新其它顶点到起点的距离。
  3. 重复1,2步,直到所有顶点都在集合S里,此时,终点存的距离就是终点到起点的最短距离。

朴素版Dijkstra例题

ACWING849. Dijkstra求最短路 I
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。

输入格式
第一行包含整数 n 和 m。

接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 −1。

数据范围
1≤n≤500,
1≤m≤105,
图中涉及边长均不超过10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N=520;
int st[N],g[N][N],dist[N];
int n,m;
int Dijkstra()
{memset(dist,0x3f,sizeof dist);dist[1]=0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++){if(!st[j]&&(dist[t]>dist[j]||t==-1))t=j;}st[t]=1;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()
{ios::sync_with_stdio(false);cin.tie(0);int x,y,z;memset(g,0x3f,sizeof g);cin>>n>>m;while(m--){cin>>x>>y>>z;g[x][y]=min(g[x][y],z);}cout<<Dijkstra()<<'\n';return 0;
}

核心思想和注意点:

  • 朴素版Dijkstra算法用邻接矩阵来存储图
  • 起点到起点的距离初始化为0,其余顶点到起点的距离初始化为无穷大
  • 因为有重边,所以在输入图时要多加一步判断,保证选重边里权重最小的:
    g[x][y]=min(g[x][y],z);

ACWING850. Dijkstra求最短路 II
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为非负值。

请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。

输入格式
第一行包含整数 n 和 m。

接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 −1。

数据范围
1≤n,m≤1.5×105,
图中涉及边长均不小于 0,且不超过 10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 150010;
int st[N], h[N], e[N], ne[N], dist[N], w[N], idx;
int n, m;
void add(int x, int y, int z)
{e[idx] = y;ne[idx] = h[x];w[idx] = z;h[x] = idx++;
}
int Dijkstra()
{memset(dist, 0x3f, sizeof dist);priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});while(!heap.empty()){PII t = heap.top();heap.pop();int distance = t.first, ver = t.second;if(st[ver])continue;st[ver] = 1;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()
{ios::sync_with_stdio(false);cin.tie(0);int x, y, z;memset(h, -1, sizeof h);cin >> n >> m;while(m--){cin >> x >> y >> z;add(x, y, z);}cout << Dijkstra() << '\n';return 0;
}

核心思想和算法:

  • 用小根堆来实现算法,比起朴素版,寻找距离最短的结点的效率快了
  • 要用pair来存储图的结点,pair记载了两个信息,距离和顶点编号。距离用来堆排序,顶点编号用来取结点时识别结点。
  • pair的first一定是距离,因为堆排序是按距离排的。
  • if(st[ver]) continue;这段代码的含义是,可能会有两个结点a和b同时指向c,那么在对a和b进行更新时,就会把c二次入堆,可我们只需要对c更新一次就够了,所以在第二次见到c时就无须进行for循环了,直接在算法中段停止即可。
  • 由于邻接表和堆的特点,在输入图时无需考虑重边问题,算法中会自动选择距离小的边放入堆中

Dijkstra算法(朴素,堆优化)+例题相关推荐

  1. dijkstra算法及其堆优化

    dijkstra算法及其堆优化 (个人笔记写给自己看的) 数据结构:链式前向星,优先队列 dijkstra算法: vis数组初始化为0,dis数组初始化为inf(很大的值如:0x7fffffff),设 ...

  2. Dijkstra算法和堆优化

    目录 Dijkstra介绍 算法思想 具体步骤 代码实现 Dijkstra链式向前星 优化思路 实现步骤 代码实现 Dijkstra链式向前星堆优化 优化思路 优化步骤 代码实现 参考资料(帮助理解代 ...

  3. Dijkstra算法及堆优化

    1.有向无环图的单源点最短路 其实跟之前说的最长路是一样的 思路:广搜(拓扑排序)+ DP 如下图所示: 2.一般图的单源点最短路 Dijkstra(迪杰斯特拉)算法 算法思路:每次找离起点最近的那个 ...

  4. Dijkstra算法(堆优化版求稀疏图最短路)

    南昌理工acm集训队 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959年提出的,是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题. 基本思想 Dijkstra算法是用来解决不 ...

  5. DijKstra算法普通+堆优化链式向前星

    朴素版本 #include<bits/stdc++.h> using namespace std; const int maxn = 10010; const int inf = 0x3f ...

  6. 最小生成树 Kruskal 和 Prim算法及堆优化

    目录 生成树/最小生成树是什么. 一.Kruskal算法 Kruskal模板 二.Prim算法及堆优化 1.遍历 Prim 普通模板 2.堆优化 Prim 堆优化模板 解决最小生成树的问题之前,我们先 ...

  7. 迪杰斯特拉算法及其堆优化

    迪杰斯特拉算法及其堆优化 迪杰斯特拉算法是一种求解图的单点最短路径的算法. 一句话来说就是找最近点,更新相邻距离,再找最近点,更新相邻距离 迪杰斯特拉算法的原理是 1.首先在没有中间节点的情况下,也就 ...

  8. 【Dijkstra算法】未优化版+优先队列优化版

    https://blog.csdn.net/YF_Li123/article/details/74090301 Dijkstra算法伪代码://G为图:数组d为源点到达各点的最短路径长度,s为起点 D ...

  9. dijkstra算法详解加例题分析 NOIP 2012 文化之旅

    首先说一下什么叫单源最短路径问题: 给定一个带权有向图G=(V,E),其中每条边的权是一个实数.另外,还给定V中的一个顶点,称为源.现在要计算从源到其他所有各顶点的最短路径长度.这里的长度就是指路上各 ...

  10. 第六天PAT-A1003 Emergency最短路问题Dijkstra算法(小根堆)描述及模板

    A1003 Description: 作为一个城市的急救队领导,你会得到你所在城市的一个特别地图.这张地图展示了一些由一些路径相连的几个零散的城市.每个城市的救援队总数和连接两个城市的道路的长度都标注 ...

最新文章

  1. python动态心形代码-Python数学方程式画心型图案源码示例
  2. JVM垃圾回收3——参数详解(转载)
  3. mvc @html.checkbox,MVC - @Html.CheckBoxFor
  4. 华为Mate 40 Pro概念渲染图曝光:首发屏下摄像头技术?
  5. 关于《侏罗纪世界》你应该知道的18件事
  6. html标题代码字号,HTML 标题
  7. mysql 内部 临时表_MySQL内部临时表何时使用磁盘
  8. Hibernate关系映射(三) 多对一和一对多
  9. Java练习题--员工类案例练习
  10. 使用 RabbitMQ 实现 RPC
  11. 【网络安全】威胁情报信息
  12. EditText修改软键盘输入法的Enter键的按钮文字
  13. 通俗理解ROC曲线(Receiver Operating Characteristic Curve)
  14. GC—MS常见数据库有哪些,NIST和AMDIS有什么作用?
  15. 江西“葫芦夫妻”的“甜蜜”事业
  16. Kindle下线在即 使用cpolar建立自己的电子书图书馆
  17. 将 Cpar 文件导入 2019 版的 Carsim 后,无法打开 video+plot 是什么问题?
  18. ubuntu安装bochs别忘了bochs-x
  19. 博通wifi驱动详解(二)
  20. ch03:算数运算(长沙师范学院)

热门文章

  1. 使用短生命周期容器(Ephemeral Containers)构建微服务化的工作流
  2. github使用介绍
  3. MySQL字符集设置及字符转换(latin1转utf8)
  4. android中页面跳转以及数据在Activity之间的传递
  5. DataGridView - Column named XXX cannot be found
  6. 用WPF+MongoDB开发房产信息收集器(3)——MongoDB入门
  7. sourceTree外部工具解决冲突
  8. oracle 自定义比较函数
  9. Android 自定义View可拖动移动位置及边缘拉伸放大缩小
  10. Windows环境bugfree搭建