对于固定起点的最短路算法,我们称之为单源最短路算法。单源最短路算法很多,最常见的就是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会无法赋值因为所有的点都遍历过了,造成变量没有初始化而程序崩溃。

代码如下:

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. const int maxn = 10;
  6. int map[maxn][maxn], dis[maxn];
  7. int n;                                                         //点数
  8. void init()
  9. {
  10. for (int i = 1; i <= n; i++)
  11. for (int j = 1; j <= n; j++)
  12. map[i][j] = 0x3f3f3f;
  13. memset(dis, 0, sizeof(dis));
  14. }
  15. void dijkstra(int v0)
  16. {
  17. for (int i = 1; i <= n; i++)
  18. dis[i] = map[v0][i];
  19. map[v0][v0] = 0;
  20. for (int i = 1; i < n; i++)                                //注意循环的次数,如果到n,最后一次所有的map[i][i]都是0,pos找不到值会崩溃,如果初始化为0则dis[i]最后全是0(dis[0] = 0)
  21. {
  22. int min_dis = 0x3f3f3f3f,pos;
  23. for (int j =1; j <= n; j++)
  24. {
  25. if (map[j][j] && dis[j] < min_dis)                 //遍历所有点找到距离v0最小的点,记录下距离,并将其加入已计算的集合,将其编号用pos记录下来
  26. min_dis = dis[pos = j];
  27. }
  28. map[pos][pos] = 0;                                     //用map[i][i]来表示某个点是否被访问过,节省空间
  29. for (int j = 1; j <= n; j++)
  30. {
  31. dis[j] = min(dis[j], dis[pos] + map[pos][j]);      //用新添加的点来更新一边dis
  32. }
  33. }
  34. }
  35. int main()
  36. {
  37. freopen("input.txt", "r", stdin);
  38. int m,u,v,w,target;
  39. scanf("%d%d", &n,&m);
  40. init();
  41. while (m--)
  42. {
  43. scanf("%d%d%d", &u, &v, &w);
  44. map[u][v] = map[v][u] = w;
  45. }
  46. scanf("%d", &target);
  47. dijkstra(target);
  48. for (int i = 1; i <= n; i++)
  49. {
  50. printf("%d : %d\n", i, dis[i]);
  51. }
  52. return 0;
  53. }

但要注意的是,dijkstra不能计算含有负权的图的最短路,因为一直加负数始终会比原来的小。

【算法】单源最短路——Dijkstra的更多相关文章

  1. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  2. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

  3. 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)

    题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...

  4. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  5. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  6. 单源最短路——Dijkstra模板

    算法思想: 类似最小生成树的贪心算法,从起点 v0 每次新拓展一个距离最小的点,再以这个点为中间点,更新起点到其他点的距离. 算法实现: 需要定义两个一维数组:①vis[ i ] 表示是否从源点到顶点 ...

  7. 单源最短路Dijkstra算法——matlab实现

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

  8. 单源最短路(Dijkstra算法)

    #返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...

  9. Dijkstra算法——单源最短路算法

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

随机推荐

  1. canvas与svg

    canvas与svg都是用于在网页上绘制图形(位图). canvas是HTML5新出来的一个标签,用来定义一块画图的区域(canvas本身没有绘制能力),用JavaScript来画图,可以绘制路径.矩 ...

  2. SPOJ 8093 JZPGYZ - Sevenk Love Oimaster

    思路 可以用复杂度不对的做法水过去 相当于求parent树子树中的颜色种数,可以离线后树状数组(HH的项链,询问右端点排序之后维护last),dsu on tree,莫队都可以 但是也可以记录每个点上 ...

  3. async/await 的使用

    async : 使用 async 修饰符可将方法.lambda 表达式或匿名方法指定为异步. 如果对方法或表达式使用此修饰符,则其称为异步方法 await: await 运算符应用于异步方法中的任务, ...

  4. 图解HTTP学习笔记

    前言: 一直觉得自己在HTTP基础方面都是处于知其然,不知其所以然的样子.最近利用空闲时间拜读了一下图解HTTP,写篇博客记录一下读书笔记. TCP三次握手: ① 发送端首先发送一个带SYN标志的数据 ...

  5. 使用jQuery修改带有!important 的强制样式

    我们习惯性的会用这种方法进行修改: $(".test").css("width","100px !important"); 但是往往是修改失 ...

  6. java反射使用和源码解析

    1         反射 1.1            什么是反射 正射:指的是我们知道类的定义和类中的方法名称,直接先创建对象,然后通过对象去调用方法.例如: Apple apple = new A ...

  7. 2018-2019-2 20165303《网络攻防技术》Exp5 MSF基础应用

    实践目标 1.一个主动攻击实践 ms17_010(成功) ms08_067(成功) 2.一个针对浏览器的攻击 ms13-008(成功唯一) ms11-050(失败) ms13-069(成功唯一) ad ...

  8. vue文件上传控件

    下载地址:https://pan.baidu.com/s/1Z3pFh2J3xWa8YYnLoseasg 使用方式: <upload ref='upload' action-url='' :mu ...

  9. [GXOI/GZOI2019]旧词

    很像LNOI 2014 LCA那道题. 同样的套路,离线以后直接扫描线. k=1的话就是原题. 考虑一般情况. 原本的做法是对x到根的这条链做一下区间+1操作,目的是为了是的在深度为i的位置得到的贡献 ...

  10. 阿里云yum配置

    CentOS 安装源列表见 CentOS Mirror List.本文使用阿里云安装源安装官方源和扩展源.其他安装源也可以参考. 依次执行命令. #使用 yum-config-manager 软件包命 ...