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. git环境搭建

    Linux kernel  的官方 GIT地址是: http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git 可以从这个地 ...

  2. Jalopy 之 HelloWorld —— Jalopy 在 MyEclipse 下的安装与使用

    如果你要问我Jalopy是什么.我只能告诉你“它是一个格式化代码的工具”.因为我也是一个初学者. 如果你也是初次接触,那一起来学习下吧! ·安装 1.首先,下载资源 下载地址:http://sourc ...

  3. 自定义Eclipse的 “宏命令”

    在Eclipse中有些常用的固定的东西可以定义一个“宏命令”,就不用重复地做一些工作.就像在 Preferences > Java > Code Style > Code Templ ...

  4. Android Touch(4)我不知道的MotionEvent(*)

    1,MotionEvent的复制或构造 有时候可能要保存一个MotionEvent, 它的构造方法是匿名的,不能直接创建,对外提供的获取对象的接口是静态的obtain方法,可以从一个MotionEve ...

  5. leetcode:Add Two Numbers

    题目描述:You are given two linked lists representing two non-negative numbers. The digits are stored in ...

  6. js之json

    关于json不了解的,请点击:http://www.json.org/json-zh.html json对象的属性必须要用双引号,值为字符串类型也只能使用双引号,例:{"name" ...

  7. HDU 1850 (Nim博弈 取胜方案数) Being a Good Boy in Spring Festival

    考虑到Bouton定理的证明过程,设n个数的Nim和(异或和)为X,其最高位的1在第k位,那么n个数中一定有个y的第k为也是个1. 将y的数量变为X xor y,那么n的数的Nim和为0,便转为先手必 ...

  8. mongodb数据备份与还原

    1)简单数据的导出与导入导出:./mongoexport -d test -c users -o /tmp/users.out 导入:./mongoimport -d test -c users /t ...

  9. pandas

  10. The Guide To Understanding mysqlreport

    The Guide To Understanding mysqlreport This guide to understanding mysqlreport explains everything t ...