继续最短路径!说说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. mongo 内存限制wiredTigerCacheSizeGB = 10

    [root@iZ2zed126f44v90yv59ht3Z rabbitmq]# cat /usr/local/mongodb/mongodb.confport = 27017dbpath = /us ...

  2. @RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别

    1.@RequestMapping 国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应 ...

  3. svn命令使用常见问题

    1.如何添加文件 ? svn add filename svn ci -m "add file" 2. svn ci 出现冲突 经常多人开发时难免多个人修改同一个文件导致冲突发送, ...

  4. 软件测试工具MonkeyTalk使用方法

    1.简单介绍 MonkeyTalk软件测试工具由两部分构成:MonkeyTalk IDE 和 MonkeyTalk Agents MonkeyTalk IDE是Eclipse平台的工具,工能是:对iO ...

  5. 几种常见的DIV边框样式

    <html> <head> <title>边框样式</title> </head> <body> <p style=bor ...

  6. 【转】DirectorySearcher.Filter属性说明

    DirectorySearcher.Filter属性扩充申明 DirectorySearcher mySearcher = new DirectorySearcher(entryOU, "( ...

  7. JAVA 多线程机制(二)

    主要内容 1.理解线程的并发性 2.线程的同步 3.线程的常用方法   上一章中由于线程的并发性导致了多线程的执行总是会出现一些问题..线程的并发性是程序员不可控制 的,也是不可避免的,线程的并发性往 ...

  8. 那些有关求解next数组的算法

    next数组的历史 有关字符串的模式匹配算法中,比较容易写出的是朴素的匹配算法也就是一种暴力求解方式,但是由于其时间复杂度为子串长度和主串长度的乘积,例如strlen(subStr) = n,strl ...

  9. mui.back()返回刷新功能

    使用场景:操作某个步骤需要获取用户信息,如果用户未登陆,则跳转登录页面,登陆成功之后使用mui.back()返回父页面,父页面必须刷新. 子页面:登陆页 父页面:跳转登录页的页面 1. 在子页面初始化 ...

  10. Spring学习笔记——Spring依赖注入原理分析

    我们知道Spring的依赖注入有四种方式,各自是get/set方法注入.构造器注入.静态工厂方法注入.实例工厂方法注入 以下我们先分析下这几种注入方式 1.get/set方法注入 public cla ...