Bellman-Ford算法

来源:互联网 发布:如何做好网络推广工作 编辑:程序博客网 时间:2024/06/06 00:52

 Bellman-Ford算法流程

第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。

第二,进行循环,循环下标为从1n1n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。
第三,遍历途中所有的边(edgeuv)),判断是否存在这样情况:
dv) > d (u) + w(u,v)

则返回false,表示途中存在从源点可达的权为负的回路。

有向图的Bellman-Ford算法。。。。。

#include<iostream>  #include<cstdio>  using namespace std;    #define MAX 0x3f3f3f3f  #define N 1010  int nodenum, edgenum, original; //点,边,起点    typedef struct Edge //边  {      int u, v;      int cost;  }Edge;    Edge edge[N];  int dis[N], pre[N];    bool Bellman_Ford()  {      for(int i = 1; i <= nodenum; ++i) //初始化          dis[i] = (i == original ? 0 : MAX);      for(int i = 1; i <= nodenum - 1; ++i)          for(int j = 1; j <= edgenum; ++j)              if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) //松弛(顺序一定不能反~)              {                  dis[edge[j].v] = dis[edge[j].u] + edge[j].cost;                  pre[edge[j].v] = edge[j].u;              }              bool flag = 1; //判断是否含有负权回路              for(int i = 1; i <= edgenum; ++i)                  if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost)                  {                      flag = 0;                      break;                  }                  return flag;  }    void print_path(int root) //打印最短路的路径(反向)  {      while(root != pre[root]) //前驱      {          printf("%d-->", root);          root = pre[root];      }      if(root == pre[root])          printf("%d\n", root);  }    int main()  {      scanf("%d%d%d", &nodenum, &edgenum, &original);      pre[original] = original;      for(int i = 1; i <= edgenum; ++i)      {          scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost);      }      if(Bellman_Ford())          for(int i = 1; i <= nodenum; ++i) //每个点最短路          {              printf("%d\n", dis[i]);              printf("Path:");              print_path(i);          }      else          printf("have negative circle\n");      return 0;  }  



0 0