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

对于单源最短路径问题,一般有两种经典解法: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. Gradle 1.12用户指南翻译——第四十七章. Build Init 插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  2. Unity使用UGUI进行VR游戏的界面开发

    原文链接:http://gad.qq.com/article/detail/7181505 本文首发腾讯GAD开发者平台,未经允许,不得转载 我不知道有多少同学是跟我一样,在开发VR游戏中,是使用的面 ...

  3. CentOS7.2安装Weblogic12c出现的问题

    Weblogic12c安装到步骤:Prerequisite  Checks 时,会进行操作系统版本的校验,即checking  operating  system  certification. 此处 ...

  4. Swift中String和NSString的一个不同之处

    我们知道在Swift中String和NSString是可以互相转换使用的-额-应该是在绝大数情况下可以互相转换使用.在某些情况下可能还有一丝丝略微的差别:比如在涉及到处理字符串中字符索引的时候. 我们 ...

  5. Scheme N皇后

    (define (range n) (define (recur n) () '() (cons n (recur (- n ))))) (recur (- n ))) (define (flatte ...

  6. HTTP状态码总结

    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码.有些 App 端接口与 HTML 接口用的是同一个,所以做移动端开发也有必要了解一下HTTP状态码 ...

  7. Android自定义View(二、深入解析自定义属性)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51468648 本文出自:[openXu的博客] 目录: 为什么要自定义属性 怎样自定义属性 ...

  8. XMPP(三)-安卓即时通讯客户端

    由于时间原因,所以更新比较慢 ,还请大家谅解,此次是对上篇文章中的安卓客户端初级版本进行的一次更新优化,在这次更新后,就有那么一点样子了,可以拿的出手了,呵呵,还在关注的同学也可以及时下载更新.此次主 ...

  9. mysql-workbench工具update(更新)失败的解决办法

    是因为安全模式的保护,所以我们需要设置一下: 如下:windows下是edit–>preferences–>SQL Editor 把右边的最后一行,"safe update&qu ...

  10. 12 PopupWindow

    PopupWindow创建方式 PopupWindow pop = new PopupWindow() PopupWindow pop = new PopupWindow(上下文, 填充宽, 填充高) ...