【算法】单源最短路——Dijkstra
对于固定起点的最短路算法,我们称之为单源最短路算法。单源最短路算法很多,最常见的就是dijkstra算法。
dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么i和j之间的任意两点s,t之间也一定是最短路,非常好证,如果s,t之间不是最短路,那么必然存在最短路,那么i到j也不是最短路造成了矛盾。
而dijkstra就是运用这样的思想,把起点首先放进一个集合S中,其他的点在另一个集合中,每次取起点经过集合S中的点可达的最短路的点,加入到集合S中,并且根据新加入的店刷新一遍最短路。直到所有的点都在集合S中。
如上图,假设以1为起点,dis[i]为起点到i点的最短距离,如果没法直达则为INF
第一次:S中只有1,那么1能直达的点有2,3,取路径最短的3加入S,并更新一遍dis,发现6可达,dis[6] = 20;
第二次:S中有1,3,可达的有2,6,取2,则4,5可达,dis[4] = 21,dis[5] = 10;
第三次:S中有1,2,3,可达的有4,5,6,取5,到4多了新路径且比原来近,更新dis[4] = 13;
第四次:S中有1,2,3,5,可达的有4,6,取4,到6多了新路径且比原来近,更新dis[6] = 15;
第五次:S中有1,2,3,4,5,可达的有6,只有6不在S中,取6,不更新,完成算法
要注意的是外围循环是除了起点外的点数,如果多一次,pos会无法赋值因为所有的点都遍历过了,造成变量没有初始化而程序崩溃。
代码如下:
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- using namespace std;
- const int maxn = 10;
- int map[maxn][maxn], dis[maxn];
- int n; //点数
- void init()
- {
- for (int i = 1; i <= n; i++)
- for (int j = 1; j <= n; j++)
- map[i][j] = 0x3f3f3f;
- memset(dis, 0, sizeof(dis));
- }
- void dijkstra(int v0)
- {
- for (int i = 1; i <= n; i++)
- dis[i] = map[v0][i];
- map[v0][v0] = 0;
- for (int i = 1; i < n; i++) //注意循环的次数,如果到n,最后一次所有的map[i][i]都是0,pos找不到值会崩溃,如果初始化为0则dis[i]最后全是0(dis[0] = 0)
- {
- int min_dis = 0x3f3f3f3f,pos;
- for (int j =1; j <= n; j++)
- {
- if (map[j][j] && dis[j] < min_dis) //遍历所有点找到距离v0最小的点,记录下距离,并将其加入已计算的集合,将其编号用pos记录下来
- min_dis = dis[pos = j];
- }
- map[pos][pos] = 0; //用map[i][i]来表示某个点是否被访问过,节省空间
- for (int j = 1; j <= n; j++)
- {
- dis[j] = min(dis[j], dis[pos] + map[pos][j]); //用新添加的点来更新一边dis
- }
- }
- }
- int main()
- {
- freopen("input.txt", "r", stdin);
- int m,u,v,w,target;
- scanf("%d%d", &n,&m);
- init();
- while (m--)
- {
- scanf("%d%d%d", &u, &v, &w);
- map[u][v] = map[v][u] = w;
- }
- scanf("%d", &target);
- dijkstra(target);
- for (int i = 1; i <= n; i++)
- {
- printf("%d : %d\n", i, dis[i]);
- }
- return 0;
- }
但要注意的是,dijkstra不能计算含有负权的图的最短路,因为一直加负数始终会比原来的小。
【算法】单源最短路——Dijkstra的更多相关文章
- 利用分支限界法求解单源最短路(Dijkstra)问题
分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...
- 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)
题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...
- 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)
题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...
- 单源最短路——dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...
- 单源最短路dijkstra算法&&优化史
一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...
- 单源最短路——Dijkstra模板
算法思想: 类似最小生成树的贪心算法,从起点 v0 每次新拓展一个距离最小的点,再以这个点为中间点,更新起点到其他点的距离. 算法实现: 需要定义两个一维数组:①vis[ i ] 表示是否从源点到顶点 ...
- 单源最短路Dijkstra算法——matlab实现
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...
- 单源最短路(Dijkstra算法)
#返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...
- Dijkstra算法——单源最短路算法
一.介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他各个节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 适用于有 ...
随机推荐
- graph easy绘制ascii简易流程图
graph-easy 日常我们经常需要画一些简易流程图,但是如果使用visio等工具来作图,一则略显大材小用,二则图片导出后再要粘贴.相比下,如果可以简单的用一些text的图来表达,则会简单的多.比如 ...
- iOS __block 关键字的底层实现原理 -- 堆栈地址的变更
默认情况下,在block中访问的外部变量是复制过去的.但是可以加上 __block 来让其写操作生效. 原理: Block 不允许修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址. ...
- easyUI提交不跳转
$('#loginForm').form('submit');为easyUI封装的异步提交方法,页面不跳转,可得到返回值. $('#loginForm').submit();为js自带原生表单提交方法 ...
- django url 反响解析,视图
1. 内容回顾 1. 模板语言(字符串替换) 1. 母版和继承 1. 什么时候用母版? html页面有重复的代码,把它们提取出来放到一个单独的html文件. (比如:导航条和左侧菜单) 2. 子页面如 ...
- Bigger-Mai 养成计划,subprocess模块
subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system.os.spawn*.os.popen*.commands.*等.subproce ...
- TeamView工具在提示“似乎用于商用环境”的处理方式
第一种:通过修改这个文件/也有可能删除(没有尝试过)
- 前端——Bootstrap
Bootstrap介绍 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快速开发Web应用程序而设计的一套前端工具包. 以前自己写的html的 ...
- Asp.net 按钮幕布遮盖效果实现方式
Asp.net button按钮点击后想要实现幕布效果来等待服务器端执行完成,这种需求虽说看起来很简单,但真实做起来并不是那么简单,涉及了很多细节点,而对于深入理解asp.net button生命周期 ...
- UVA - 11468 (AC自动机+动态规划)
建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG ...
- Log4net详细说明
1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual S ...