Bellman-Ford算法可以大致分为三个部分
第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。
第二,进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。
第三,遍历途中所有的边(edge(u,v)),判断是否存在这样情况:d(v) > d (u) + w(u,v)则返回false,表示途中存在从源点可达的权为负的回路。
具体描述可见《算法导论》P362。
伪代码:
BELLMAN-FORD(G, w, s) 1 INITIALIZE-SINGLE-SOURCE(G, s) 2 for i ← 1 to |V[G]| - 1 3 do for each edge (u, v) ∈ E[G] 4 do RELAX(u, v, w) 5 for each edge (u, v) ∈ E[G] 6 do if d[v] > d[u] + w(u, v) 7 then return FALSE 8 return TRUE
附一个Bellman-Ford算法的模板
/*==================================================*\ | BellmanFord 单源最短路O(VE) | 能在一般情况下,包括存在负权边的情况下,解决单源最短路径问题 | INIT: edge[E][3]为边表 | CALL: bellman(src);有负环返回0;dist[i]为src 到i 的最短距 | 可以解决差分约束系统: 需要首先构造约束图,构造不等式时>=表示求最小值, 作为最长路,<=表示求最大值, 作为最短路 (v-u <= c:a[u][v] =c ) \*==================================================*/ #define typec int // type of cost const typec inf=0x3f3f3f3f; // max of cost int n, m, pre[V], edge[E][3]; typec dist[V]; int relax ( int u, int v, typec c) { if (dist[v] > dist[u] + c) { dist[v] = dist[u] + c; pre[v] = u; return 1; } return 0; } int bellman (int src) { int i, j; for (i=0; i<n; ++i) { dist[i] = inf; pre[i] = -1; } dist[src] = 0; bool flag; for (i=1; i<n; ++i) { flag = false; // 优化 for (j=0; j<m; ++j) //松弛 { if( 1 == relax(edge[j][0], edge[j][1], edge[j][2]) ) flag = true; } if( !flag ) break; } for (j=0; j<m; ++j) { if (1 == relax(edge[j][0], edge[j][1], edge[j][2])) return 0; // 有负圈 } return 1; }