继续最短路径!说说Bellman—Ford算法

思路:假设起点为s,图中有n个顶点和m个边,那么它到任一点(比如i)的最短路径

最多可以有n-1条(没有回路就是n-1条);因为最短路径中不可能包含回路:如果有正权

回路(正圈),那么最短路径肯定不走这个回路(不绕圈,绕圈会增加权值,直接走),

如果有负权回路(负圈),那么就不存在最短路径,因为每走一次负圈权值就减少一次,

根本不存在最小值。
我们再次利用松弛的办法:每一轮,我们枚举所有的边,看不能不能缩短两个顶点之间的

距离。到i顶点的缩短就意味着可以经过一个另一个的顶点来缩短起点到i顶点的距离,换

句话说,最短距离多了一条边。每进行一轮松弛,最短距离就可能多一条边,而最短路径

最多有n-1条边,所以进行n-1轮次松弛就可以了。
核心代码如下:
for(int k=1;k<=n-1;k++)
 for(int i=1;i<=m;i++)
  if(dis[v[i]]>dis[u[i]]+w[i])
   dis[v[i]] = dis[u[i]] + w[i];
现在分析:首先要注意的是使用该算法时,我们没有使用邻接矩阵或者邻接表。而是采用

三个数组u,v,w来记录每一条边(因为我们只利用边)。三个对应的值:u[i],v[i],w[i]

表示从u[i]到v[i]有一条权值为w[i]边。
接下来每一轮我们都枚举每一条边,来尝试能否缩短起点s到该边的终点v[i]的距离。注

意,如果s不能到达u[i],那么dis[u[i]]就是INF,这个松弛就是失败的(理解一下)。
这样的算法是有优化的余地的,我们可以看到每一轮松弛中是有失败的,也就浪费了时间

。之后还可以优化。

另外还可以用Bellman-Ford算法来计算图中是否有负圈。如果我们增加轮数为n,那么如

果第n轮有dis[]有更新就说明是有负圈的。

代码如下

# include<iostream>

using namespace std;

int dis[];//保存临时值(或者确定值)
int u[], v[], w[]; const int INF = ; int main()
{
int n, m;//n个顶点,m条边。 cin >> n >> m; for (int i = ; i < m; i++)//读入m条边
cin >> u[i] >> v[i] >> w[i]; //初始化dis数组
for (int i = ; i < n; i++)
dis[i] = INF; dis[] = ;//还是默认顶点0为起点s //Bellman-Ford算法核心
for (int i = ; i < n - ; i++)//进行n轮松弛
for (int k = ; k < m; k++)//枚举m条边
if (dis[v[k]] > dis[u[k]] + w[k])
dis[v[k]] = dis[u[k]] + w[k]; for (int i = ; i < n; i++)
cout << dis[i] << " "; system("pause"); return ;
}

图论之最短路径(2)——Bellman-Ford算法的更多相关文章

  1. Bellman - Ford 算法解决最短路径问题

    Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...

  2. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  3. Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】

    题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...

  4. poj1860 bellman—ford队列优化 Currency Exchange

    Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22123   Accepted: 799 ...

  5. uva 558 - Wormholes(Bellman Ford判断负环)

    题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...

  6. 图论之最短路径floyd算法

    Floyd算法是图论中经典的多源最短路径算法,即求任意两点之间的最短路径. 它可采用动态规划思想,因为它满足最优子结构性质,即最短路径序列的子序列也是最短路径. 举例说明最优子结构性质,上图中1号到5 ...

  7. 数据结构与算法--最短路径之Bellman算法、SPFA算法

    数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...

  8. 求最短路径的三种算法: Ford, Dijkstra和Floyd

    Bellman-Ford算法 Bellman-Ford是一种容易理解的单源最短路径算法, Bellman-Ford算法需要两个数组进行辅助: dis[i]: 存储顶点i到源点已知最短路径 path[i ...

  9. ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

    两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...

随机推荐

  1. 应用层timer_libc_posix timer

    应用层除了通过setitimer/getitimer设置获取timer外,还可通过timer_create()等一系列函数实现应用层timer功能. 应用流程 The timers created b ...

  2. kernel headers

    linux/delay延迟相关函数,长延时ssleep msleep(睡眠等待),短延时mdelay udelay(忙等待) linux/sched.h进程相关的头文件, struct task_st ...

  3. 试验如何通过审核Google AdSense——我跟谷歌ads杠上啦

    http://www.hankcs.com/appos/webhost/apply-google-ads.html —————————————————————————————————————————— ...

  4. 让PHP7达到最高性能的几个Tips

    PHP7 已经发布了,作为PHP十年来最大的版本升级,最大的性能升级,PHP7在多放的测试中都表现出很明显的性能提升,然而,为了让它能发挥出最大的性能,我还是有几件事想提醒下. PHP7 VS PHP ...

  5. 在jsp页面比较时间的大小

    //-----------------------------------------------------controller-------------------- Calendar c = C ...

  6. 传说中的纯CSS圆角代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  7. python中的argsort函数

    >>> import numpy >>> help(numpy.argsort) Help on function argsort in module numpy. ...

  8. USB2.0学习笔记连载(三):通用USB驱动程序解析

    对于USB驱动的开发,读者可以使用Windows DDK.DriverStudio等多种开发工具来实现USB的驱动,但是驱动程序的开发过程都比较复杂,而且很容易致使USB主机内存泄露而死机.那么对于笔 ...

  9. 关于B/S和C/S模式

    B/S注重的是 1.服务想玩游戏的时候,就出现想看电影的时候,就出现不用下载客户端太麻烦看个电影还要下载一大堆东西,不看了 2.维护升级软件不用一台一台地重新更新,百度一直在更新,但是我们感觉不到 3 ...

  10. udp编程中,一次能发送多少个bytes为好?

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,我这里仅对    像ICQ一类的发送聊天消息 ...