Bellman-Ford算法 - 有向图单源最短路径
2017-07-27 08:58:08
writer:pprp
参考书目:张新华的《算法竞赛宝典》
Bellman-Ford算法是求有向图单源最短路径的,dijkstra算法的条件是图中任意一条边的权都是正的;BF算法可以解决存在负边权的图;
算法流程分为三个部分:
- 初始化,将除源点外的所有顶点的最短距离的估计值D[i] = +无穷,D[sourse] = 0;
- 迭代求解:反复对每条边进行松弛操作,使得每个顶点的最短距离D[i]估计值主讲逼近其最短距离;运行n-1次
- 检验负权回路:通过松弛操作判断每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回FALSE表名问题无解;否则返TRUE,输出D[i]的值
例题:虫洞
代码如下:
#include <iostream> using namespace std; int w[1001][1001],d[1001]; int n,m; //n 是点的个数, m是边的个数 int change; //? void init() { cin >> n >> m; int x,y,v; for(int i = 1; i <= n ; i++) for(int j = 1; j <=n; j++) w[i][j] = INT_MAX; for(int i = 1; i <= m; i++) { cin >> x >> y >> v; w[x][y] = v;//单向通道,边的权值为v } } void bellman_ford(int x) { int i,j,k; for(i=1; i<=n; i++) //initial array d d[i] = w[x][i]; d[x] = 0; //到自己距离为0 for(k=1; k<=n-1; k++) for(j = 1; j >=n ; j++) //松弛 for(i = 1; i <=n ; i++) if((w[i][j]!=INT_MAX)&&d[i]!=INT_MAX&&d[j]>d[i]+w[i][j]) d[j] = d[i]+w[i][j]; change = 1; for(i =1; i<=n; i++) //松弛操作判断是否存在负权回路 for(j=1; j<=n; j++) if(w[i][j]!=INT_MAX&&d[i]!=INT_MAX&&d[j]>d[i]+w[i][j]) change = 0; if(change) cout <<"Not possoble"<<endl; else cout <<"Possible"<<endl; } int main() { init(); bellman_ford(1); return 0; }
代码改变世界