单源最短路径指的是从一个顶点到其它顶点的具有最小权值的路径。我们之前提到的广度优先搜索算法就是一种无权图上执行的最短路径算法,即在所有的边都具有单位权值的图的一种算法。单源最短路径算法可以解决图中任意顶点间的最短路径。

对于单源最短路径问题,一般有两种经典解法:1.对于有权值为负的图,采用Bellman-Ford算法;2.对于权值全为正的图,常采用Dijkstra算法。本文介绍Bellman-Ford算法,下一篇介绍Dijkstra算法。

Bellman-Ford算法适用于权值可以为负、无权值为负的回路的图,这比Dijkstra算法的使用范围要广。其基本思想为:首先假设源点到所有点的距离为无穷大,然后从任一顶点u出发,遍历其它所有顶点vi,计算从源点到其它顶点vi的距离与从vi到u的距离的和,如果比原来距离小,则更新,遍历完所有的顶点为止,即可求得源点到所有顶点的最短距离。下面用实例说明:

上图中,顶点内的值表示该顶点到s顶点的距离。在下面的具体程序实现中,我用0 1 2 3 4代表 s t x y z.

具体程序实现如下:

#include<stdio.h>
#define M 10//边数
#define N 5//顶点数
#define MAX 10000

int BellmanFord(int dist[N][N],int d[N],int i);

int flag1=0;
int flag2=0;

typedef struct
{
	int startvex;
	int endvex;
	int length;
}edge;
edge T[M];
void main()
{
	int dist[N][N]={{0,6,MAX,7,MAX},
					{MAX,0,5,8,-4},
					{MAX,-2,0,MAX,MAX},
					{MAX,MAX,-3,0,9},
					{2,MAX,7,MAX,0}};//图的邻接矩阵
	int d[N];
	int num=0;
    num=BellmanFord(dist,d, 0);//计算下标为0的顶点到其它顶点的距离,num用于统计边数
	for(int i=0;i<N;i++)//打印到各个顶点之间的距离
		printf("%d ",d[i]);
	printf("\n");
	for(int j=0;j<num;j++)//打印考虑过的边
		printf("start=%d,end=%d,lenth=%d\n",T[j].startvex,T[j].endvex,T[j].length);
}

int BellmanFord(int dist[N][N],int d[N],int i)
{
	for(int j=0;j<N;j++)//初始化
		d[j]=MAX;
	d[i]=0;
	int num=0;

	for(int k=0;k<N-1;k++)
	{
		for(int ii=0;ii<N;ii++)
			for(int jj=0;jj<N;jj++)
			{
				if(dist[ii][jj]!=MAX)
				{
					if(d[jj]>(d[ii]+dist[ii][jj]))//不断更新距离
					{
						d[jj]=d[ii]+dist[ii][jj];//当原节点到jj节点的距离大于
						                         //原节点到ii节点的距离与从ii节点到jj节点的距离和时更新
						T[num].startvex=ii;
						T[num].endvex=jj;
						T[num].length=dist[ii][jj];
						num++;
					}
				}
			}
	}
	for(int ii=0;ii<N;ii++)
	for(int jj=0;jj<N;jj++)//有权值为负的回路的情况
	{
		if(d[jj]>(d[ii]+dist[ii][jj]))
			return 0;
	}
return num;

}

结果显示如下:

注意:上述的结果与前面图解的一致,但是用到的边有7条比前面图解的阴影部分的边多3条,这是因为图解过程中省略了中间的一些步骤,直接得到最小权值时的情况。通过阴影部分的边,我们可以轻松的找到最短路径所经过的顶点,当然,当图比较复杂时,就该写程序来打印最短路径了。

注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明

原文:http://blog.csdn.net/tengweitw/article/details/17451125

作者:nineheadedbird

【算法导论】单源最短路径之Bellman-Ford算法的更多相关文章

  1. 单源最短路径问题之dijkstra算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...

  2. 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)

    文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...

  3. Bellman-Ford算法 - 有向图单源最短路径

    2017-07-27  08:58:08 writer:pprp 参考书目:张新华的<算法竞赛宝典> Bellman-Ford算法是求有向图单源最短路径的,dijkstra算法的条件是图中 ...

  4. 【算法】单源最短路径和任意两点最短路径总结(补增:SPFA)

    [Bellman-Ford算法] [算法]Bellman-Ford算法(单源最短路径问题)(判断负圈) 结构: #define MAX_V 10000 #define MAX_E 50000 int ...

  5. 51nod 1445 变色DNA ( Bellman-Ford算法求单源最短路径)

    1445 变色DNA 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1 ...

  6. 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  7. 【算法】Bellman-Ford算法(单源最短路径问题)(判断负圈)

    单源最短路问题是固定一个起点,求它到其他所有点的最短路的问题. 算法: 设 d[i]  表示 起点 s 离点 i 的最短距离. [1.初始化]  固定起点s,对所有的点 , 如果 i =  s ,  ...

  8. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  9. 单源最短路径问题1 (Bellman-Ford算法)

    /*单源最短路径问题1 (Bellman-Ford算法)样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9] */ ...

  10. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...

随机推荐

  1. 0426html常用标签属性

    一.基础语法 标签:作为网页的最小单元 1.双标签 内容的容器 2.单标签 控制性内容 注释    每一个模块都要写清楚注释 二.基本结构 <!DOCTYPE html>          ...

  2. Python 3.3.2 round函数并非"四舍五入"

    对于一些貌似很简单常见的函数,最好还是去读一下Python文档,否则当你被某个BUG折磨得死去活来时,还不知根源所在.尤其是Python这种不断更新的语言.(python 2.7 的round和3.3 ...

  3. Webpack 2 设置为从当前文件夹逐级向上查找模块

    比较实用, 当你在cd到子文件夹运行webpack时,你可能想要require文件夹js里面的一些模块, 但你又想将祖先的js文件夹作为fallback.这样设置即可: module.exports ...

  4. Ubuntu 16.04: How to resolve libqt5x11extras5 (>= 5.1.0) but it is not going to be installed

    Issue: When you install Virtualbox 5.1 on Ubuntu 16.04, you may encounter following error: root@XIAY ...

  5. 安卓高级3 Android应用Design Support Library完全使用实例

    原作者:http://www.open-open.com/lib/view/open1433385856119.html 1 背景 上周一年一度的Google IO全球开发者大会刚刚结束,Google ...

  6. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap,第 1 部分: kprobe

    kprobe 的原理.编程接口.局限性和使用注意事项 本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprobe以及促使开发该工具的先驱DTr ...

  7. Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/44171115 大家好,欢迎继续回到Android属性动画完全解析.在上一篇文章当中 ...

  8. java 随机数高效生成

    分享牛,分享牛原创.近期去面试经常被问到java如何生产随机数,以及生成很大的字符串保证不能重复,还要考虑性能,之前本人面试别人的时候,可能不会问这个问题.既然这个java随机数问题经常被问到,那咱们 ...

  9. [Android]聊聊ActionMode

    最近一段时间都没有更新文章,趁工作之余,更新一篇. 今天介绍一个很常见效果也最容易被忽略的弹出框:ActionMode.主要是ActionMode使用和自己使用过程中遇到的一些问题,相对还是比较简单的 ...

  10. android 调试工具ADB命令详解

    adb是什么? adb的全称为Android Debug Bridge,就是起到调试桥的作用. 通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具. ...