最短路算法总结

最近一周为了省ACM准备,系统地学习了一下最短路算法。

大致有三种Dijkstra算法、Bellman-ford算法、Floyd算法。

下面就三种算法的适用范围以及代码详解做出描述。

首先Dijkstra算法

朴素Dijkstra算法是最简单、易上手的一个处理最短路的算法,当然代码也很容易理解,即使对于算法小白也很容易掌握,但是缺点是时间复杂度是O(n^2),一般对于小于等于1e3次方的点数可以使用,对于再大的就会超时。

对于朴素Dijkstra算法我完成了以下几道题目,以下就题目思路与代码展开讨论。

首先是一个模板题,题目大意是,有n(n<=1000)个点,有m条边,每条边连接着两个权值,点数从0开始,求从0开始到各个点的最短路径的值是多少?

很显然这是一个最短路径的题,而且题目中n的大小满足朴素Dijkstra的范围,可以使用这个算法。

此算法的大体逻辑可以进行一下归纳:

  1. 初始化边权
  2. 标记起点
  3. 进行n轮迭代,遍历n个点,找到最小的边以及对应的端点
  4. 用此端点去更新其他边,最终找到最短路径值。

每一步代表的含义都写在注释里啦,认真看注释就可以理解啦!

特别注意一下,对于朴素Dijkstra算法可以用二维数组来存值,而不必使用结构体。同时要注意无向图,以及有重复边时的处理,以及刚进入Dijksta算法时,对dis数组的赋值。

当然朴素Dijkstra算法大多数情况只能处理模板题,稍微变形可以会不可以,但是掌握了朴素Dijkstra算法对于后面的堆优化的Dijkstra算法也有很大的帮助喔,因为代码思想是一样的。

Bellman-ford算法

这个算法主要是针对负边权问题做处理的,对于存在负边权的图,不可以使用Dijkstra算法。但是虽然Bellman-ford算法可以处理带负边权,但是不可以处理带有负边且成环的图。

Bellman-ford算法代码写起来较为简洁。但是需要引入一个结构体存边的信息。

 Floyed算法

floyd算法应该是这三个中最简单的一个了,优点是可以处理负边环的图,缺点是时间复杂度非常高O(n^3)。这里贴一个Floyd算法的变形题吧,是POJ上的Frogger,相信大家应该都看过。

http://poj.org/problem?id=2253

这道题目给的数据范围非常小,所以我考虑的是用Floyd算法。题目的大体意思是在某一位置的青蛙想要跳到另一位置青蛙的位置,想要求在这两个点中的最小必要跳跃距离。刚开始没太明白题意,直接当成最短路来做了,但是其实不是的,这个最小跳跃距离通俗一点讲就是找一条最短路上的任意两个点的最大距离。所以我们要保证找到的路径是最短的,同时在这条路径上找到一个最大值,为什么是最大值呢?因为他求得是必要跳跃距离,必须要跳的一个最大距离,这个题真的是很考察语文功底呀~但是后面在做的时候发现其实很多这种变形题,所以只要解决了这一个,以后遇到其他类似的也能大体知道思路啦

这个题主要在理解最小跳跃距离,可以好好想一下啦,一定要自己理解,理解了还是很简单的~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值