算法导论 ch24 单源最短路径 Bellman-Ford

来源:互联网 发布:知乎 庄雅婷 编辑:程序博客网 时间:2024/05/20 10:53


基本算法实现如下,

/home/a/j/nomad2:cat bellman.CPP #include <iostream>using namespace std;typedef int typec;const typec inf = 0x3f3f3f3f;const int V = 10, E = 20;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;}void input() {        cin >> n >> m;        for (int i = 0; i < m; i++) {                cin >> edge[i][0] >> edge[i][1] >> edge[i][2];        }}void display() {        for (int i = 0; i < n; i++) {                cout << dist[i] << " ";        }        cout << endl;        for (int i = 0; i < n; i++) {                cout << pre[i] << " ";        }        cout << endl;}int main() {        input();        bellman(0);        display();        return 0;}

测试用例为书上的图24-4,
/home/a/j/nomad2:cat input5 100 1 60 3 71 2 51 3 81 4 -42 1 -23 2 -33 4 94 0 24 2 7/home/a/j/nomad2:cat input|./a.out 0 2 4 7 -2 -1 2 3 0 1 

优化:SPFA(Shortest-Path Faster Algoithm),参考:

http://hi.baidu.com/jzlikewei/blog/item/94db7950f96f995a1038c2cd.html

http://hi.baidu.com/jzlikewei/blog/item/5343d134b54c6f48251f14cd.html


POJ

From: http://hi.baidu.com/sunshine_0316/blog/item/36f4c7a3d9113aaacaefd055.html

三、 学以致用

POJ 1201 Intervals 差分约束系统

设S(i)为 0..i-1 中在最终序列中的的整数个数。则约束条件如下:

S(b)-S(a) >= c

0 <= S(i+1) - S(i) <= 1 <==> S(i+1)-S(i) >= 0;

S(i)-S(i+1) >= -1

注意本题要求的是最小值, 而按照>=号建图后发现图中有负环, 怎么办呢?

其实很简单, 本题求的不是最短路, 而是最长路! Bellman_ford即可!

POJ 1275 Cashier Employment 出纳员的雇佣

黑书上有详细讲解

POJ 1364 King 差分约束系统

这个题目构图之后, 只需要用bellman_ford判断是否有负圈.

构图方法:

首先进行转换:a[j]+...+a[j+m] = a[1]+...a[j+m] - (a[1]+...+a[j-1]) = sum[j+m] -


sum[j-1] >(<) ki. 差分约束只能全部是<=或者(>=).

第二步转换: sum[j+m]-sum[j-1] <= ki-1 或者 sum[j-1]-sum[j+m] <= -ki-1.

约束图构造好后就是简单的Bellman-Ford了!

POJ 1716 Integer Intervals 是1201的简单版本, 贪心算法能够得到更好的效果.

POJ 2983 Is the Information Reliable?

差分约束题, 处理一下等号的情况, 然后普通的Bellman_ford

POJ 3159 Candies 最短路径

Bellman-Ford超时, Dijkstra算法可以高效解决, SPFA(队列)居然超时...SPFA修改为堆栈实现就过了.

POJ 3169 Layout 差分约束

Bellman-Ford 和 SPFA 实现均可

POJ 3259 Wormholes 判断负权回路

TOJ 2976 Path 单纯的最短路径 可练习SPFA

ZOJ 3033 Board Games 首先,DFS判断可达性,不可达直接输出infinity结束,可达,bellman-ford判断是否存在负环,存在输出infinity,否则,输出最短距离。

原创粉丝点击