继续最短路径!说说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. 内核模块module传参

    linux 2.6允许用户insmod的时候往内核模块里面传递参数,它主要使用module_param宏定义来实现这一功能. 参数应用 module_param(name, type, perm); ...

  2. 检查 Linux 服务器性能

    如何用十条命令在一分钟内检查 Linux 服务器性能 如果你的Linux服务器突然负载暴增,报警短信快发爆你的手机,如何在最短时间内找出Linux性能问题所在?来看Netflix性能工程团队的这篇博文 ...

  3. linux实现防止恶意扫描 PortSentry

    linux实现防止恶意扫描 PortSentry   脚本 open 摘要: 端口做为服务器的大门安全很重要,当服务器运行很多服务时并向外提供服务,为防止有人恶意侦测服务器用途,可使用portsent ...

  4. mysql数据库对时间进行默认的设置

    //----------------------------------------------------------sql语句----------------------------------- ...

  5. tp-01 搭建过程

    1:拷贝ThinkPHP框架系统文件夹自己的www目录中的tp-shop文件夹中 2:新建自己的项目文件(比如:shop)夹与ThinkPHP框架系统文件夹在同一级目录(当然也可以不同) 3: 在tp ...

  6. absolute绝对定位的非绝对定位用法

    总结: position为absolute的元素如果没有设置left, top等值与left:0;top:0;的的效果是不一样的.例如一个div中有个absolute属性元素,其没有left或是top ...

  7. 如何对抗、预防 SQL注入 攻击

    一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...

  8. 《FPGA全程进阶---实战演练》第二章之PCB layout注意事项以及投板几点说明

           上一篇博客讲述了各个部分的原理图,那么根据原理图画出PCB,其实PCB是一门很大的学问,想要掌握谈何容易.就笔者在画PCB时的一些注意事项做一些说明.        1.电源部分的电源线 ...

  9. Hibernate中createCriteria即QBC查询的详细用法

    现在假设有一个Student类,内有id,name,age属性String hql = "from Student s";按照以前的做法,我们通常是Query query = se ...

  10. 【MySQL】字符串截取之substring_index

    substring_index(str,delim,count)       str:要处理的字符串       delim:分隔符       count:计数 例子:str=www.baidu.c ...