1.最短路

最短路,顾名思义,最短的路径。我们把边带有权值的图称为带权图。边的权值可以理解为两点之间的距离。一张图中任意两点之间会有不同的路径相连。最短路径就是指连接两点的这些路径中最短的一条。我们有四种算法可以有效地解决最短路径问题,但是当出现负边权时,有些算法不适用。

2. Floyd算法(解决多源最短路径):时间复杂度O(n^3), 空间复杂度(n^2)

推荐一篇博客。写的非常易懂:Floyd

  • 分类:多源最短路径算法。
  • 作用:1.求最短路。 2.判断一张图中的两点是否相连。
  • 优点:实现极为简单
  • 缺点:只有数据规模较小且时空复杂度都允许时才可以使用
    = 思想:3层循环,第一层枚举中间点k,第二层与第三层枚举两个端点i,j。若有dis[i][j] > dis[i][k] + dis[k][j] 则把dis[i][j]更新成dis[i][k] + dis[k][j](原理还是很好理解的)。
  • 实现:
    (a)初始化:点i,j如果有边相连,则dis[i][j] = w[i][j]。如果不相连,则dis[i][j] = 0x7fffffff(int极限值),表示两点不相连(或认为相隔很远)。
    (b)算法代码:
for(int k = 1; k <= n; k++)  //枚举中间点(必须放最外层)for(int i = 1; i <= n; i++)  //枚举端点iif(i != k)for(int j = 1; j <= n; j++)  //枚举端点jif(i != j && j != k && dis[i][j] > dis[i][k] + dis[k][j])dis[i][j] = dis[i][k] + dis[k][j];

完整代码

 1     #include 2     int main()  3     {  4     int e[10][10],k,i,j,n,m,t1,t2,t3;  5     int inf=99999999; //用inf(infinity的缩写)存储一个我们认为的正无穷值6     //读入n和m,n表示顶点个数,m表示边的条数7         scanf("%d %d",&n,&m);  8     //初始化9     for(i=1;i<=n;i++)
10     for(j=1;j<=n;j++)
11     if(i==j) e[i][j]=0;
12     else e[i][j]=inf;
13     //读入边
14     for(i=1;i<=m;i++)
15         {
16             scanf("%d %d %d",&t1,&t2,&t3);
17             e[t1][t2]=t3;
18         }
19     //Floyd-Warshall算法核心语句
20     for(k=1;k<=n;k++)
21     for(i=1;i<=n;i++)
22     for(j=1;j<=n;j++)
23     if(e[i][j]>e[i][k]+e[k][j] )
24                         e[i][j]=e[i][k]+e[k][j];
25     //输出最终的结果
26     for(i=1;i<=n;i++)
27         {
28     for(j=1;j<=n;j++)
29             {
30                 printf("%10d",e[i][j]);
31             }
32             printf("\n");
33         }
34     return 0;
35     }

Floyd-Warshall算法不能解决带有“负权回路”(或者叫“负权环”)的图,因为带有“负权回路”的图没有最短路。

  • 如果是一个没有边权的图,把相连的两点间距离设为dis[i][j] = true,不相连的两点设为dis[i][j] = false,用Floyed算法的变形:
for(int k = 1; k <= n; k++)  //枚举中间点for(int i = 1; i <= n; i++)  //枚举端点iif(i != k)for(int j = 1; j <= n; j++)  //枚举端点jif(i != j && j != k)dis[i][j] = dis[i][j] || (dis[i][k] && dis[k][j]);(判断是否相连)

3. 迪杰斯特拉算法(解决单源最短路径)

  • 分类:
    单源最短路径算法。
  • 适用于:
    稠密图(侧重对点的处理)。
  • 时间复杂度:
    1.朴素:O(N^2)
    2.堆优化:O(n * logn)
  • 缺点:
    不能处理存在负边权的情况。
  • 算法思想:
    把点分为两类,一类是已经确定最短路径的点,称之为“标记点”;另一类则是还未确定最短路径的点,称之为“未标记点”。如果要求出一个点的最短路径,就是把这个“未标记点”变成“标记点”,从起点到“未标记点”的最短路径上的中转点在这个时刻只能是“标记点”。
    Dijkstra的算法思想,就是一开始将起点到起点的距离标记为0,而后进行n次循环,每次找出一个到起点距离dis[u]最短的点u,将它从“未标记点”变为“标记的点”。随后枚举所有的“未标记的点”vi,如果以此“标记的点”为中转点到达“未标记的点”vi的路径dis[u] + w[u][vi]更短的话,这将它作为vi的“更短路径”dis[vi](此时还不确定是不是vi的最短路径)。
    就这样,我们每找到一个“标记的点”,就尝试着用它修改其他所有的:“未标记的点”,故每一个终点一定能被它的最后一个中转点所修改,而求得最短路径。
  • 优化思想:
    利用堆(优先队列),把冗杂的枚举查找变成更加快速的堆直接弹出。
  • 实现思路:
    (a)初始化:dis[v] = oo (v != s); dis[s] = 0; pre[s] = 0;
    (b)for(int i = 1; i <= n; i++)
    1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的。
    2.u标记为已确定最短路径。
    3.for与u相连的每个未确定最短路径的顶点v。
(伪代码)
if(dis[u] + w[u][v] < dis[v]){dis[v] = dis[u] + w[u][v];pre[v] = u;}
#define inf 99999999
/***构建邻接矩阵edge[][],且1为源点***/
for(i = 1; i <= n; i++) dst[i] = edge[1][s];
for(i = 1; i <= n; i++) book[i] = 0;
book[1] = 1;
for(i = 1; i <= n-1; i++){//找到离源点最近的顶点u,称它为新中心点min = inf;for(j = 1; j <= n; j++){if(book[j] == 0 && dst[j] < min){min = dst[j];u = j;}}book[u] = 1;//更新最短路径数组for(k = 1; k <= n; k++){if(edge[u][k] < inf && book[k] == 0){if(dst[k] > dst[u] + edge[u][k])dst[k] = dst[u] + edge[u][k];         }}
}

4. Bellman算法

  • 分类:
    单源最短路径算法。
  • 适用于:
    稀疏图(侧重于对边的处理)。
  • 优点:
    可以求出存在负边权情况下的最短路径。
  • 缺点:
    无法解决存在负权回路的情况。
  • 时间复杂度:
    O(NE),N是顶点数,E是边数。(因为和边有关,所以不适于稠密图)
  • 算法思想:
    很简单。一开始认为起点是“标记点”(dis[1] = 0),每一次都枚举所有的边,必然会有一些边,连接着“未标记的点”和“已标记的点”。因此每次都能用所有的“已标记的点”去修改所有的“未标记的点”,每次循环也必然会有至少一个“未标记的点”变为“已标记的点”。
  • 算法实现:
    初始化:dis[s] = 0; dis[v] = oo(v != s); pre[s] = 0;
(伪代码)
for(int i = 1; i <= n - 1; i++)for(int j = 1; j <= E; j++)  //注意要枚举所有边,不能枚举点if(dis[u] + w[j] < dis[v])  //u, v分别是这条边连接的两个点{dis[v] = dis[u] + w[j]pre[v] = u;}

最短路算法(3种算法)相关推荐

  1. 最短路的几种算法及其优化(模板)

    一.Dijkstra 算法 dijkstra算法适用于边权为正的情况,求单源最短路,适用于有向图和无向图 模板伪代码: 清除所有点的标号 设d[0]=0,其余d[i]=INF: 循环n次{ 在所有未标 ...

  2. LCA 朴素算法+树差分倍增+Tarjan算法 三种算法实现c++代码实现

    哔哩哔哩up视频:https://www.bilibili.com/video/BV1nE411L7rz?t=379 转载:http 文章目录 树差分 & 倍增LCA Tarjan 朴素算法 ...

  3. 最短路小结(三种算法+各种常见变种)

    额,博主只是做了几(约数)道题而已,写这篇小结纯粹想留作纪念(勿喷,但是可以交流)(那啥,转载的话注明一下来源..打字不容易..) 最短路呢,包括三种算法,但是各有各的变种,其中变化有很多. 简单记录 ...

  4. python OpenCV 图片相似度 5种算法

    原始两张图片: 代码运行结果如下. 5种算法 值哈希算法.差值哈希算法和感知哈希算法都是值越小,相似度越高,取值为0-64,即汉明距离中,64位的hash值有多少不同. 三直方图和单通道直方图的值为0 ...

  5. 【含泪提速!】一文全解相似度算法、跟踪算法在各个AI场景的应用(附代码)

    大家好,我是cv君,大家是否为深度学习算法速度感到困扰?本次cv君倾力分享一个优秀的方法,通过相似度+跟踪方案优化速度问题,并提高了检测.分割算法稳定性,附带代码,一起肝起来吧~ 今天给大家全解一下图 ...

  6. 深入浅出:四种常用的最短路算法+两种常用生成树算法+网络流常用算法大礼包

    文章目录 一.最短路径 1:Dijkstra & 堆优化 & why not 负权边? 2:Bellman-Ford:迭代与松弛 2(2): 进阶版:Spfa & why 队列 ...

  7. 爱因斯坦谜题解答(三种算法比较)

    爱因斯坦谜题:     在一条街上有颜色互不相同的五栋房子,不同国籍的人分别住在这五栋房子力,每人抽不同品牌的香烟,喝不同的饮料,养不同的宠物.已知如下情况: 1.  英国人住红色房子里. 2.  瑞 ...

  8. 随机洗牌:哪一种算法是正确的?

    2019独角兽企业重金招聘Python工程师标准>>> 原文 记得当年搞NOIp时,我犯过一个相当严重的错误:错误地把Floyd算法的i, j, k三层循环的位置顺序搞颠倒了.直到准 ...

  9. 最短路算法 :Bellman-ford算法 Dijkstra算法 floyd算法 SPFA算法 详解

     本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并不低所以,本文的代码 存图只 ...

最新文章

  1. iOS架构-cocoapods打包静态库(依赖私有库、开源库、私有库又包含静态库)(14)
  2. 使用SKIP-GRANT-TABLES 解决 MYSQL ROOT密码丢失
  3. oracle性能优化总结
  4. 三、css 和 js 的装载与执行
  5. 是按压还是触摸_一文读懂,选联想还是华为?Matebook 14锐龙版和YOGA 14s、小新Pro13怎么选?...
  6. 并发高?可能是编译优化引发有序性问题
  7. gridsearchcv参数_Python机器学习库Sklearn系列教程(21)-参数优化
  8. mysql 函数 数字转字串_mysql中字符串和数字的互转函数
  9. terminal采用公钥免密访问服务器
  10. 优秀技能经验及对java学习展望
  11. teraterm 执行sql_teraterm自动或定时执行远程命令
  12. 对于学习编程,你认为英语和数学哪个重要?
  13. Blue Coat:2015年数据安全趋势七大预测
  14. html中引用名言标签,CSS3 培根名人名言引用全屏居中样式设计
  15. Oracle 查询一个小时之前表的数据
  16. matlab读int16读文件_[转载]Matlab中的textread textscan读取文本文件
  17. 可以看游资的app_新游资APP:高评分App是如何养成的?
  18. python如何创建一个文件夹_利用Python怎么创建一个文件夹
  19. 高效办公!Python 批量生成PDF文档
  20. 「需求工程」需求工程-介绍(第1部分)

热门文章

  1. 基于jquery的带事件显示功能的日历板插件calendar.js
  2. 使用getGenericSuperclass()和getActualTypeArguments()将DAO做成泛型
  3. jquery click点击事件重复执行多次
  4. BZOJ 3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(博弈论)
  5. Swift学习笔记(10)--枚举
  6. 记次浙大月赛 134 - ZOJ Monthly, June 2014
  7. Android开发14——监听内容提供者ContentProvider的数据变化
  8. CnBlogs自定义博客样式
  9. [数据结构]-循环队列
  10. pdoModel封装