#include<stdio.h>
#define max 0xffffff
int g[][]; //图的邻接矩阵
int dist[];
int n;//顶点个数
int m;//边个数
struct Edge
{
int u, v, w; //边:起点、终点、权值
};
Edge e[];
bool bellman_ford(int n)//bellman-ford算法
{
int i, k, t,j;
for(i=;i<n;i++)
dist[i]=g[][i];//初始化
for(i=;i<=n-;i++)
{ /*假设第k条边的起点是u,终点是v,以下循环考虑第k条边是否会使得源点v0到v的
最短距离缩短,即判断dist[edges[k].u] + edges[k].w < dist[edges[k].v] 是否成立*/
for(j=;j<n;j++)
{
printf("%d ",dist[j]);
}
printf("\n");
for(k=;k<=m;k++)
{
t=dist[e[k].u]+e[k].w;
if(dist[e[k].u]<max&&t<dist[e[k].v])
{
dist[e[k].v] = t;
}
}
}
/*以下是检查,若还有更新则说明存在无限循环的负值回路*/
for(k = ; k < m; k ++)
{
if(dist[e[k].u] != max &&dist[e[k].u] + e[k].w < dist[e[k].v])
{
return false;
}
}
return true;
} int main()
{
scanf("%d %d",&n,&m);
int i,j;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
g[i][j]=max;
g[i][i]=;
}
for(i=;i<=m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[i].u=a;
e[i].v=b;
e[i].w=c;
g[a][b]=c;
}
for(i=;i<n;i++)
{
for(j=;j<n;j++)
printf("%d ",g[i][j]);
printf("\n");
}
bellman_ford(n);
for(i=;i<n;i++)
{
printf("%d\n",dist[i]);
} return ;
} /* 7 10
0 1 6
0 2 5
0 3 5
1 4 -1
2 1 -2
2 4 1
3 2 -2
3 5 -1
4 6 3
5 6 3 Press any key to continue */
Bellman-Ford算法:
为了能够求解边上带有负值的单源最短路径问题,Bellman(贝尔曼)和Ford(福特)提出了从源点逐次绕过其他顶点,以缩短到达终点的最短路径长度的方法。
 
 
Bellman-Ford算法思想
 
Bellman-Ford算法构造一个最短路径长度数组序列dist 1 [u], dist 2 [u], …, dist n-1 [u]。其中:
vdist 1 [u]为从源点v到终点u的只经过一条边的最短路径长度,并有dist 1 [u] =Edge[v][u];
vdist 2 [u]为从源点v最多经过两条边到达终点u的最短路径长度;
vdist 3 [u]为从源点v出发最多经过不构成负权值回路的三条边到达终点u的最短路径长度;

……

vdist n-1 [u]为从源点v出发最多经过不构成负权值回路的n-1条边到达终点u的最短路径长度;
算法的最终目的是计算出dist n-1 [u],为源点v到顶点u的最短路径长度。
 
 
ü采用递推方式计算 dist k [u]。
v设已经求出 dist k-1 [u] , u = 0, 1, …, n-1,此即从源点v最多经过不构成负权值回路的k-1条边到达终点u的最短路径的长度。
v从图的邻接矩阵可以找到各个顶点j到达顶点u的距离Edge[j][u],计算min{ dist k-1 [j] + Edge[j][u] } ,可得从源点v绕过各个顶点,最多经过不构成负权值回路的k条边到达终点u的最短路径的长度。
v比较dist k-1 [u]和min{ dist k-1 [j] + Edge[j][u] } ,取较小者作为dist k [u]的值。
 

递推公式(求顶点u到源点v的最短路径):

dist 1 [u] = Edge[v][u]

dist k [u] = min{ dist k-1 [u], min{ dist k-1 [j] + Edge[j][u] } }, j=0,1,…,n-1,j≠u

struct Edge
{
int u, v, w; //边:起点、终点、权值
};
Edge e[];
void bellman_ford(int n)//bellman-ford算法
{
int i, k, t;
for(i=;i<=n;i++)
dist[i]=g[][i];//初始化
for(i=;i<=n;i++)
{
for(k=;k<=m;k++)
{
t=dist[e[k].u]+e[k].w;
if(dist[e[k].u]<max&&t<dist[e[k].v])
{
dist[e[k].v] = t;
}
}
}
}

代码实现:0(v*e)

 #include<stdio.h>
#define max 0xffffff
int g[][]; //图的邻接矩阵
int dist[];
int n;//顶点个数
int m;//边个数
struct Edge
{
int u, v, w; //边:起点、终点、权值
};
Edge e[];
bool bellman_ford(int n)//bellman-ford算法
{
int i, k, t,j;
for(i=;i<n;i++)
dist[i]=g[][i];//初始化
for(i=;i<=n-;i++)
{ /*假设第k条边的起点是u,终点是v,以下循环考虑第k条边是否会使得源点v0到v的
最短距离缩短,即判断dist[edges[k].u] + edges[k].w < dist[edges[k].v] 是否成立*/
for(j=;j<n;j++)
{
printf("%d ",dist[j]);
}
printf("\n");
for(k=;k<=m;k++)
{
t=dist[e[k].u]+e[k].w;
if(dist[e[k].u]<max&&t<dist[e[k].v])
{
dist[e[k].v] = t;
}
}
}
/*以下是检查,若还有更新则说明存在无限循环的负值回路*/
for(k = ; k < m; k ++)
{
if(dist[e[k].u] != max &&dist[e[k].u] + e[k].w < dist[e[k].v])
{
return false;
}
}
return true;
} int main()
{
scanf("%d %d",&n,&m);
int i,j;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
g[i][j]=max;
g[i][i]=;
}
for(i=;i<=m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[i].u=a;
e[i].v=b;
e[i].w=c;
g[a][b]=c;
}
for(i=;i<n;i++)
{
for(j=;j<n;j++)
printf("%d ",g[i][j]);
printf("\n");
}
bellman_ford(n);
for(i=;i<n;i++)
{
printf("%d\n",dist[i]);
} return ;
} /* 7 10
0 1 6
0 2 5
0 3 5
1 4 -1
2 1 -2
2 4 1
3 2 -2
3 5 -1
4 6 3
5 6 3 Press any key to continue */
 
 0(n*n*n)
 void bellman_ford(int n)//bellman-ford算法
{
int i, k, t,j;
for(i=;i<=n;i++)
dist[i]=g[][i];//初始化
for(k=;k<=n;k++)
{
for(j=;j<=n;j++)
{
for(i=;i<=n;i++)
{
if(g[i][j]<max&&dist[i]+g[i][j]<dist[j])
dist[j]=dist[i]+g[i][j];
}
}
}
}

Bellman-Ford算法的更多相关文章

  1. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  2. Bellman - Ford 算法解决最短路径问题

    Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...

  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. ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

    两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...

  7. 图论算法——最短路径Dijkstra,Floyd,Bellman Ford

    算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...

  8. POJ 2240 Arbitrage (Bellman Ford判正环)

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:27167   Accepted: 11440 Descri ...

  9. poj1860 兑换货币(bellman ford判断正环)

    传送门:点击打开链接 题目大意:一个城市有n种货币,m个货币交换点,你有v的钱,每个交换点只能交换两种货币,(A换B或者B换A),每一次交换都有独特的汇率和手续费,问你存不存在一种换法使原来的钱更多. ...

  10. ACM/ICPC 之 Bellman Ford练习题(ZOJ1791(POJ1613))

    这道题稍复杂一些,需要掌握字符串输入的处理+限制了可以行走的时间. ZOJ1791(POJ1613)-Cave Raider //限制行走时间的最短路 //POJ1613-ZOJ1791 //Time ...

随机推荐

  1. Grovvy初识

    1.Groovy和Java对比 Groovy的松散的语法允许省略分号和修饰符 除非另行指定,Grovvy的所有内容都为public Grovvy允许定义简单脚本,同时无需定义正规的class对象 Gr ...

  2. 详解js中的闭包

    前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...

  3. Struts2:java.lang.NoSuchFieldException: resourceEntries at java.lang.Class.getDeclaredField(Class.java:1901)

    今天在做Struts2的测试用例时候,程序能正常跳转,但是在Console却报了一个错误,如下: java.lang.NoSuchFieldException: resourceEntries at ...

  4. Excel如何查找名字重复的数据

    来源于:http://jingyan.baidu.com/article/414eccf6091ff86b431f0aec.html Cokery今天在帮助同事整理数据的时候遇到了一个难题,就是在Ex ...

  5. MVC4学习笔记(一)

    1.查询 1)Controllers /// <summary> /// 数据上下文对象 /// </summary> OumindBlogEntities db = new ...

  6. Java-编写一个jdbc操作类

    1.通过读取文件配置 package 数据库操作类; /* * Db.java Created on 2007年8月20日, 上午 8:37 */ import java.io.*; import j ...

  7. Lucene -- 实时索引

    lucene的实时搜索可以分成:实时和近实时的搜索. 实时只能依靠内存了. 近实时可以用lucene中提供org.apache.lucene.index.DirectoryReader.open(In ...

  8. 【HDU 5007】Post Robot

    Description DT is a big fan of digital products. He writes posts about technological products almost ...

  9. Java编程思想学习(九) 异常处理

    java的异常处理机制可以使程序有极好的容错性,让程序更加的健壮.所谓的异常,就是指的阻止当前方法或作用域继续执行的问题,,当程序运行时出现异常时,系统就会自动生成一个Exception对象来通知程序 ...

  10. 4.Android下拉列表框spinner学习

    下拉列表框被广泛使用,诸如淘宝.京东等手机端经常可以看到这个部件身影,今天就来学习下它. 首先布局文件增加代码:如图 接下来在values下增加arrays.xml 如图               ...