Bellman-Ford算法模板

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 i1 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;

}

 

你可能感兴趣的:(for)