算法介绍

Dijkstra算法是基于贪心思想,用于实现只含有正权边的单源最短路径问题,单源路径是从一个固定起始点出发到其余各点的路径。

算法过程:

首先,获取起始点到其余点的距离,然后从起始点出发,每次选取一个距离起始点最近的节点X作为中转点,比较通过中转点X到达其余路径直接到达其余路径,哪种情况最短并将最短的情况进行更新后,再选取除X以外另一个到起始点最近的点。以此方式,逐层递进,到达终点。

题目描述

给定一个 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

题目分析

Dijkstra适用于稠密图,因此选用邻接矩阵存储数据。

Dijkstra是基于贪心思想的算法,算法过程:

首先,确定一个起始点,将各顶点到起始点的距离初始化为无穷大。然后再将与初始点相邻的其余点依次进行对比,选择距离初始点最近的一个点作为中转点(第一次选取的点为起始点自身,之后将会选取其余点作为中转点)。

然后,以该中转点再来探索与其相邻的点j 的距离,当起始点到点j 的距离小于起始点通过中转点再到点j 的距离,则将后者作为优选路径,完成全部邻接点的更新。


以此类推,依次逐步向目标点延伸,找到最短路径。

具体图示过程可参考:AcWing 849. Dijkstra求最短路 I:图解 详细代码

在表示无穷大时使用0x3f3f3f3f,在表示无穷小时使用0xc0c0c0c0

参考文章:
使用0x3f3f3f3f表示无穷大

c语言正负无穷的设置

算法实现

#include <stdio.h>const int N = 510, INF = 0x3f3f3f3f;  // INF:无穷大
int n, m;
int g[N][N], dist[N];       // 邻接矩阵g和最短距离数组dist
//int pre[N];               // 构建前驱数组,记录最短路径序列中各节点的直接前驱
bool visit[N];              // 访问记录数组visitint dijkstra(){for(int i = 0; i <= n; i++)     dist[i] = INF;     // 初始化为无穷大dist[1] = 0;        // 编号为1的结点到自身的距离for(int i = 0; i < n; i++){                      // 每遍历一次向前走一步,一共n个点遍历n次int t = 0;                                   // 存储访问点for(int j = 1; j <= n; j++){                 // 选取中转点if(!visit[j] && dist[j] < dist[t])      t = j;  // 每次选取距离原点最近的点作为中转点}visit[t] = true;                            // 标记已被访问过for(int j = 1; j <= n; j++){                // 更新原点0至各点的距离if(dist[t] + g[t][j] < dist[j]){        // 判断经过之前的路径近还是经过中间点t近dist[j] = dist[t] + g[t][j];//pre[j] = t;                       // 记录到达结点j的上一个结点为t}}}// if(dist[n] == INF)          // 若到n为无穷大,说明不存在由结点1到n的路径//     return -1;  // else//     return dist[n];         // 返回最短路径return dist[n] == INF ? -1 : dist[n];
}int main(){scanf("%d%d", &n ,&m);for(int i = 0; i <=n; i++)          // 初始化邻接矩阵g为无穷大for(int j = 0; j <= n; j++)if(i != j)   g[i][j] = INF;while(m--){int x, y, z;        scanf("%d%d%d", &x, &y ,&z);if(g[x][y] > z)     g[x][y] = z;        // 选取权重最小的边}printf("%d", dijkstra());// 输出最短路径//puts("");                                 //for(int i = n; i != 0; i = pre[i])       printf("%d ", i);return 0;
}

时间复杂是 O(n2+m), n 表示点数,m 表示边数。

无注释代码

#include <stdio.h>const int N = 510, INF = 0x3f3f3f3f;
int n, m;
int g[N][N], dist[N];
bool visit[N];int dijkstra(){for(int i = 0; i <= n; i++)     dist[i] = INF;dist[1] = 0;for(int i = 0; i < n; i++){int t = 0;for(int j = 1; j <= n; j++){if(!visit[j] && dist[j] < dist[t])      t = j;}visit[t] = true;for(int j = 1; j <= n; j++){if(dist[t] + g[t][j] < dist[j])         dist[j] = dist[t] + g[t][j];}}return dist[n] == INF ? -1 : dist[n];
}int main(){scanf("%d%d", &n, &m);for(int i =0; i <= n; i++)for(int j = 0; j <= n; j++)if(i != j)   g[i][j] = INF;while(m--){int x, y, z;        scanf("%d%d%d", &x, &y, &z);if(g[x][y] > z)     g[x][y] = z;}printf("%d", dijkstra());return 0;
}

参考资料:
8.11 最短路 Dijkstra 算法——信息学奥赛培训课程

55、【图】Dijkstra求最短路径(单源最短路径+边权重为正数)(C/C++版)相关推荐

  1. java 有向图 最短路径算法_java使用Dijkstra算法实现单源最短路径

    单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径.在弄清楚如何求算单源最短路径问题之前,必须弄清楚最短路径的最优子结构性质. 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j) ...

  2. Dijkstra算法(单源最短路径)

    对于有向无环图DAG,我们可以利用先拓扑排序得到顶点的一个序列,然后按照此序列进行最短路径的推进(更新当前顶点的邻接顶点的dist值),如 图的邻接表数组实现及其应用 对于有环图,通常使用的是Dijk ...

  3. 【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)

    Dijkstra算法是用来求解从某个源点到其他各顶点的最短路径(单源最短路径). 下面的Dijkstra算法的讲解都是基于这个有向图,在遇到其他问题可以类比. 算法的基本思想: 把图中的定点分成两组, ...

  4. Dijkstra算法求解单源最短路径问题

    文章目录 一 前言 二 Dijkstra 算法讲解 1. 贪心算法的证明 2. 算法实现说明 3. 初版Dijkstra算法代码 三 时间复杂度优化 1. 优化策略 2. 优化后的代码 四 结语 一 ...

  5. dijkstra算法PHP,单源最短路径(dijkstra算法)php实现

    做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi ...

  6. 【算法】Dijkstra算法(单源最短路径问题) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  7. Dijkstra模板题——单源最短路径(洛谷 P3371)

    题目选自洛谷P3371 这个数据类型可以将两个数据进行打包,比如 pair<int,int> 就是将两个int型进行打包. 而且使用优先队列时,优先队列会根据你打包的第一个数据进行排序. ...

  8. 图的最短路径之Dijkstra求单源最短路径算法(C++)

    一个有向带权图求它的单源最短路径可以使用Dijkstra算法. 单源最短路径是指:从图中的某个顶点出发,到其余各个顶点权值最小的路径. Dijkstra算法需要用到三个辅助数组: dist[max]: ...

  9. 图的单源最短路径:Dijkstra算法实现

    本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法 ...

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

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

最新文章

  1. Java Web学习总结(30)——Service层在MVC框架中的意义和职责
  2. Tomcat 7 Connector 精读(1)
  3. Java中List高效去重
  4. [CVPR2019]:专门为卷积神经网络设计的训练方法:RePr
  5. Elasticsearch 的一些关键概念
  6. linux的网络配置
  7. POJ 1719 Shooting Contest
  8. 文档下载:《两万字深度介绍分布式系统原理》.pdf
  9. java中遍历实体类,获取属性名和属性值
  10. 什么情况下你的工作最为成功_在不倦怠的情况下开始成功学习
  11. 5.4 Components -- Wrapping Content in A Component(在组件中包裹内容)
  12. 中文只占一个字符_男人宠妻的三大表现,就算只占一个,你都是嫁对了人!
  13. 信号公式汇总之拉普拉斯变换
  14. 创维E900V22C、E900V22D_S905L3A-b芯片_安卓9_当贝桌面_线刷固件包
  15. 采集侠的自动crontab脚本
  16. 《数据最重要的成员--算法》
  17. CentOs解压缩命令
  18. 观影计划:漫威电影宇宙「无限战争」系列
  19. 神经网络模型(.pth)能做些什么(使用心得)
  20. c语言编程小球运行结果是,如何用C语言编程一个滚动的小球 最好是五彩的 滚动的...

热门文章

  1. boa 传递 数据到 html,使用html网页boa这个web服务器通过cgi控制2410板子上LED灯点亮...
  2. postgresql增、删、改、查语句
  3. 用计算机发短信,怎样发短信的步骤_教你如何使用电脑发短信!
  4. 【python-sklearn】中文文本处理LDA主题模型分析
  5. 分类器对未见过类别(unseen category)的识别问题
  6. c语言质变量变,从量变到质变------------学习的必由之路
  7. 用java输出自己的名字_java 实现输出姓和名
  8. linux隧道6rd配置
  9. Linux内存泄漏检测方法总结
  10. 综合实践活动信息技术小学版第三册电子课本_人教版小学美术16年级电子课本图片+教材分析...