转自gzr的博客:https://www.cnblogs.com/TFLS-gzr/p/10381849.html,https://www.cnblogs.com/TFLS-gzr/p/10387463.html

感觉这是我目前浏览找到的最短路问题讲解中比较通俗易懂的,转载只为方便自己在遗忘的时候可以及时查阅,不必再去找,感谢作者gzr!


1 floyed算法

1)明确思想及功效:在图中求最短路还是要分开说的,分别是单源最短路和多源最短路,而floyed算法是求多源最短路的,什么是多源最短路呢?简单来说就是用完算法之后能直接写出任意两点间的最短路径长度。floyed算法在本质上是动态规划思想,不断更新最短路径的值,主要思想就是不断判断两个点是否可以通过一个点中继以刷新当前两个点最短路径的估计值,直到每两个点都判断完成。很容易理解,就不详细图解了。

2)代码如下:

for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(a[i][j]>a[i][k]+a[k][j]){a[i][j]=a[i][k]+a[k][j];}}

3)时间复杂度:O(n^3)

2 dijkstra算法

1)思想及其功效:dijkstra算法属于单源最短路算法,简单说就是用过之后,只能直接写出一点到其他任意一点的最短路径长度。这个算法类似于prim算法,找出刷新点所能到达的点,然后再继续刷新,写起来太难理解,自己都不会说了,那就具体以一幅图来讲解。

如果这个图是这样的:

  当然,图要用矩阵来存储。因为是单源最短路,只能求一个点到其他各点的最短距离,所以我们可以假设是求1号点到其他各点的最短距离。此时我们需要一个数组dis[ ]来存储1到5个顶点分别的最短路径长度。那么,在最开始时,数组里初始化为估计值,凡是1能到达的点,相应路径的长度会直接存在数组中,而不能直接到达的点则被当做正无穷,可以赋值成999999或0x3f3f3f3f等尽可能大的数,具体是什么样呢?如图所示:

       

  思考几个问题:

  •   为什么dis[1]的值是0?

    answer:因为dis[ ]数组所存的是1到各点的最短路径长度,1到1不用走,直接就到了呀,所以是0;

  •   OO是什么?

    answer:因为画图软件不会画无限符号,就用这个代替正无穷吧,写代码时可以赋成尽可能大的值。

  •   为什么有的赋值了而有的没有?

    answer:如上面所说,比如2和5,从图上看它们都和1有直接连边,可以赋进dis里,但是3和4与1无直接连边,只能通过其他点间接到达,所以先赋估计值正无穷。

  接着就把刚才刷新的2和5作为中继看一看是否可以刷新其他点的值。

  先来看一看通过2所能刷新的点,分别是3和5,dis[3]原本是正无穷,现在通过2只需要权值5就能到达,比正无穷小,就更新它,像这种操作,专业术语叫做“松弛”,同理,继续松弛操作,dis[5]的值本来为8,因为通过2来中继,3+4<8,所以更新它,继续这样操作不断循环下去,直到所有未知点全部被访问并进行松弛操作。

//蓝边表示中继,红边代表这条边不能用,绿边表示可以通过这条边来刷新。

  刚才刷新了3和4,现在通过3和4来中继。

  通过3无法继续刷新,继续看4。

  依旧没点刷新,此时,所有点都访问过了,并进行了松弛操作所有的dis[ ]全部从估计值一步步变成了确定值。

  算法演示结束。

2)主要问题

  • 怎么确定所有顶点被访问过?

  answer:可以定义一个vis[ ]数组,最开始全是0,每选出一个点,就把vis的值更新为1。

  • 先找哪个点为中继?

  answer:先选一条没有访问过且dis值最小的。

  • 有代码吗?

  answer:有,如下:

void dijkstra()
{vis[1]==0;dis[1]=0;for(int i=1;i<=n-1;i++){minn=inf;for(int j=1;j<=n;j++){if(vis[j]==0&&dis[j]<minn){k=j;minn=dis[j];}}vis[k]=1;for(int j=1;j<=n;j++){if(dis[j]>dis[k]+map[k][j]&&map[k][j]<inf)dis[j]=dis[k]+map[k][j];}}
}

3 SPFA算法

1 原理介绍

  SPFA算法和dijkstra算法特别像,总感觉自己讲的不行,同学说我的博客很辣鸡,推荐一个视频讲解,想看点这里,算法思路如下:

  1)和dijkstra一样初始化,定义一个dis[ ]数组,除了源点赋成0之外其它点都赋成正无穷,然后定义一个队列q。

  2)把队列q的队首元素取出,标志为不在队中,将其作为中继点对这个队首元素的所有出边进行松弛操作(不知道松弛操作请看这里),修改完dis值后,判断每一个修改过dis值的元素是否在队列q中,如果不在,就放入队尾;然后判断这个数入队的次数,如果大于n(n为点的个数),那就说明出现了负权回路,算法结束,否则继续。

  3)不断循环,直到队列为空。

2 实现过程中的一些问题

  •   question:怎么标志出队?

  answer:可以定义一个vis[ ]数组,最开始全部为0,表示都不在队列中,每入队一个元素x,就把vis[x]赋成1,每出队一个元素就赋值成0。

  •   question:怎么判断一个数入队次数?

  answer:可以定义一个num[ ]数组,每入队一个元素x,就num[x]++;这个可以不写,因为题目一般不会出现负权回路。

  •   question:怎么判断队列为空?

  answer:最流行的写法是while(!q.empty()),但是不太好理解,我一般会写成while(s.size()),和前一句意思相同。

3 图解演示

4 代码:

void SPFA()
{for(int i=1;i<=n;i++)dis[i]=inf;queue<int>q;q.push(1);vis[1]=1;dis[1]=0;while(q.size()){x=q.front();q.pop();vis[x]=0;for(int i=head[x];i;i=a[i].next){int s=a[i].to;if(dis[s]>dis[x]+a[i].cost){dis[s]=dis[x]+a[i].cost;if(vis[s]==0){vis[s]=1;q.push(s);}}}}
}

floyed算法、dijkstra算法、SPFA算法相关推荐

  1. 第十九章 Bellman-Ford算法(由SPFA算法逆推BF,独特解读,超级详细)

    第十九章 Bellman-Ford算法 一.SPFA算法回顾: 二.Bellman-Ford算法 1.算法推导: 1.算法模板: 三.例题: 1.问题: 2.模板: 3.分析: 一.SPFA算法回顾: ...

  2. 最短路径算法——Dijkstra and Floyd算法

    一.     前言:     这个古老的算法应该耳熟能详了吧,但是我自从从学校出来到现在,最短路径算法都没有实际运用过,最近在一个GIS项目中总算用到了,于是乎把教材重温了下,同时查阅了网上很多的资料 ...

  3. spfa算法_10行实现最短路算法——Dijkstra

    今天是算法数据结构专题的第34篇文章,我们来继续聊聊最短路算法. 在上一篇文章当中我们讲解了bellman-ford算法和spfa算法,其中spfa算法是我个人比较常用的算法,比赛当中几乎没有用过其他 ...

  4. I won't tell you this is about graph theory----zjfc bellman-ford算法与spfa算法

    题目描述 To think of a beautiful problem description is so hard for me that let's just drop them off. :) ...

  5. Bellman-ford和SPFA算法

    目录 一.前言 二.Bellman-ford算法 1.算法思想 2.算法复杂度 3.判断负圈 4.出差(2022第十三届国赛,lanqiaoOJ题号2194) 三.SPFA算法:改进的Bellman- ...

  6. Spfa算法总结(C/C++)

    文章目录 一: Spfa算法分析 二: 代码分析 一: Spfa算法分析  1. 问题介绍:  2. 问题分析:  当我们遇到单源最短路+边权为负值问题时这时候该如何处理呢?  其实我们现在就可以使用 ...

  7. dijkstra算法_最短路径问题——迪杰斯特拉算法(Dijkstra)

    假期过长,导致停更了好长时间,复习一道算法题找找感觉. 前段时间看到一篇文章,里面提到了统治世界的十大算法,其中之一就是迪杰斯特拉算法(Dijkstra),该算法主要解决的"最短路径&quo ...

  8. 一文掌握SPFA算法

    一文掌握SPFA算法 何为SPFA(Shortest Path Faster Algorithm)算法: **给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶点之间的最短距离,其显著特 ...

  9. SPFA算法求最短路

    AcWing 851. spfa求最短路 题目 https://www.acwing.com/problem/content/submission/853/ 给定一个 n 个点 m 条边的有向图,图中 ...

  10. 算法基础14 —— 图论入门之弗洛伊德算法(Floyed + Dijkstra + Bellman-Ford + SPFA)

    入门概念 带权图:如下图所示,我们把边带有权值的图称为带权图 可以将边的权值理解为两点之间的距离 一张图中任意两点间会有不同的路径相连 最短路径:最短路径就是指连接两点的这些路径中最短的一条 Floy ...

最新文章

  1. 在Lotus Domino中使用Java构建应用程序
  2. indexes和indices的区别(下标)
  3. 网易实践|千万级在线直播弹幕方案
  4. 不会Nacos的配置中心?你怎么敢的呀!如何一步步实现Nacos作为服务的配置中心(全网最详系列)
  5. kali查看共享 linux_在Linux下访问Windows共享文件夹
  6. 你还认识变量吗?Java基础学习不可略过的基本语法,简而不漏,变量的定义赋值和分类,系统认识Java中的变量有哪些?
  7. 完全CSS实现鼠标移上出现层的效果(超简单)
  8. tensorflow2.0及以上版本在使用Session模块时报错:AttributeError: module ‘tensorflow‘ has no attribute ‘Session‘ 已解决
  9. 主板定制 如何定制主板这些流程要知道
  10. Java SSM框架之MyBatis3(六)MyBatis之参数传递
  11. php 无法识别oci8,php 连接oracle 无法 启用oci8 解决办法 (摘自oracle官网)
  12. 日记 [2007年03月10日]重回blog,开始2007
  13. php phpmailer发送邮件
  14. 安川机器人dx200编程手册_【安川 】一文带了解DX200如何编程(上)
  15. 【PCBA方案】咖啡电子秤芯片方案介绍
  16. navicat 导出 oracle数据 乱码,Navicat Premium下sql导入中文乱码解决方案
  17. 一个提供用emai订阅rss的中文网站
  18. python文件重命名加日期_Python文件创建日期和Critiqu的重命名请求
  19. input。file清除。js,jquery
  20. 涂色问题 阿里编程机试题目

热门文章

  1. excel公式填充整列
  2. 闻听成都华为的员工跳楼自杀
  3. 磁盘阵列两块硬盘掉线数据恢复成功案例
  4. 数据库和MySQL的简单介绍
  5. 第十一届“挑战杯”广东省大学生课外学术科技作品竞赛总结——陈文斌
  6. python3使用付费代理和ip池的维护
  7. @keyframes详解与实例
  8. windows无法验证发行者
  9. HTML入门习题及答案
  10. Linux安装及管理应用程序