1.算法标签

BFS

2.算法概念

Bellman-Ford算法有这么一个先验知识在里面,那就是最短路径至多在N步之内,其中N为节点数,否则说明图中有负权值的回路,这样的图是找不到最短路径的。因此Bellman-Ford算法的思想如下,进行N次循环,在第 k 次循环中用dist数组记录 k 步之内到达各个顶点的最短路径长度,记做distk,然后在第k+1次循环中,遍历每条边,若有dist[v]>dist[u]+cost[u][v],则更新distk+1[v]=dist[u]+cost[u][v],并将v节点的前驱节点记为u。因此这是一个广度优先的算法,如果N次循环之后发现还未收敛,说明有负权值的回路,说明找不到最短路径。正因为如此,Bellman-Ford算法适应性比较强,但是算法复杂度较高,为O(VE),不过,经过优化的Bellman-Ford算法效率能有明显的提升。

Bellman-Ford算法维持一下几个数据结构:

  • dist数组 :第 k 次循环中用dist数组记录 k 步之内到达各个顶点的最短路径长度
  • previous数组 : 记录当前前驱

3.代码实现

头文件:

/*
areslipan@163.com
filename: Bellman_Ford.h
*/ #ifndef _BELLMAN_FORD_
#define _BELLMAN_FORD_
#include "graph.h"
#include <iostream>
bool BellmanFord(GraphAdjList *g,int start,vector<int> & previous);
#endif

 

/*
areslipan@163.com
filename : Bellman_Ford.cpp
*/ #include "Bellman_Ford.h" using namespace std;
bool BellmanFord(GraphAdjList *g,int start,vector<int> & previous)
{
vector<int>dist(g->numNodes,MYINF);
vector<int>path(g->numNodes,-1);
previous=path; dist[start]=0; for(int i=0;i<g->numNodes;++i)
{
//遍历邻接表中的每条边,进行松弛操作
for(int j=0;j<g->numNodes;++j)
{
EdgeNode * cur=g->adjList[j].firstedge;
while(cur!=NULL)
{
//找到一条k+1步之内可达的比当前路径更短的路径
if(cur->weight+dist[j] < dist[cur->adjvex])
{
dist[cur->adjvex]= cur->weight+dist[j];
previous[cur->adjvex]=j; //记录前驱
} cur=cur->next;
}
}
} for(int j=0;j<g->numNodes;++j)
{
EdgeNode * cur=g->adjList[j].firstedge;
while(cur!=NULL)
{
if(cur->weight+dist[j] < dist[cur->adjvex])return false;
cur=cur->next;
}
} return true;
}

测试文件:

 

/*
areslipan@163.com
filename : testBellmanFord.cpp
*/
#include "Bellman_Ford.h"
#include "graph.h"
using namespace std; int main()
{
GraphAdjList g;
create_adjlist_graph(&g);
show_adjlist_graph(&g);
vector<int>previous;
while(true)
{
cout<<"input start and end: ";
int start ; int end;
cin>>start>>end;
if(start==-1)break;
if(BellmanFord(&g,start,previous))
{
show_path(previous,start,end);
}
else cout<<"Negative circle exists"<<endl;
} destroy_adjlist_graph(&g);
show_adjlist_graph(&g);
system("pause");
}

 

示例输入(同Dijkstra一节中的例子):

6 18
0 1 2 3 4 5
0 1 1
1 0 1
0 2 4
2 0 4
1 2 2
2 1 2
1 4 5
4 1 5
1 3 7
3 1 7
2 4 1
4 2 1
3 4 3
4 3 3
3 5 2
5 3 2
4 5 6
5 4 6 0 5

 

示例输出:

单源最短路径的Bellman-Ford 算法的更多相关文章

  1. 单源最短路径问题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 ...

  2. 单源最短路径问题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] */ ...

  3. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

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

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

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

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

  6. 单源最短路径-迪杰斯特拉算法(Dijkstra's algorithm)

    Dijkstra's algorithm 迪杰斯特拉算法是目前已知的解决单源最短路径问题的最快算法. 单源(single source)最短路径,就是从一个源点出发,考察它到任意顶点所经过的边的权重之 ...

  7. 单源最短路径—Bellman-Ford和Dijkstra算法

    Bellman-Ford算法:通过对边进行松弛操作来渐近地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重相同时为止.该算法主要是基于下面的定理: 设G=(V,E) ...

  8. 单源最短路径Dijkstra和优先级算法

    百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...

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

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

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

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

随机推荐

  1. Hibernate —— ID的各种生成器(转)

    Hibernate中,<id>元素下的可选<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成惟一标示,所有的生成器都实现net.sf.hiberna ...

  2. 如何设置 Windows 开机启动项

    点击[开始]-[运行](或者使用快捷键-Win + R),输入 msconfig

  3. .NET动态加载用户控件并传值的方法

    ASPX.CS里的代码: VoteChat.GetType().GetProperty("vid").SetValue(VoteChat, model.id.ToString(), ...

  4. Hadoop集群(第4期)_SecureCRT使用

    1.SecureCRT简介 SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议.SecureCRT是一款用于连接运行包括Windows.UN ...

  5. 警惕rapidxml的陷阱:添加节点时,请保证变量的生命周期

    http://www.cnblogs.com/chutianyao/p/3246592.html 项目中要使用xml打包.解析协议,HQ指定了使用rapidxml--号称是最快的xml解析器. 功能很 ...

  6. JAVA的序列化与反序列化

    一.为什么要进行序列化 再介绍之前,我们有必要先了解下对象的生命周期,我们知道Java对象的生命周期,也即Java中的远程方法调用RMI也会被用到,在网络中要传输对象的话,则必须要对对象进行序列化,关 ...

  7. Python3 学习第九弹: 模块学习二之文件管理模块

    os模块 提供访问操作系统的接口 1> name 获得当前操作系统 其中 'nt' 是 windows 'posix' 是 linux 2> environ 获得当前系统的环境变量的字典, ...

  8. hdu 4647 Another Graph Game

    题意: 有N个点,M条边. 点有权值, 边有权值. Alice, Bob 分别选点. 如果一条边的两个顶点被同一个人选了, 那么能获得该权值.问 Alice - Bob? 链接:http://acm. ...

  9. 使用C++读写Excel

    1.导入Excel类型库 使用Visual C++的扩展指令#import导入Excel类型库: 1 2 3 4 5 6 7 8 9 10 11 12 #import "C:\\Progra ...

  10. UIImagePicker照片选择器

    UIImagePickerController 1.+(BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType ...