zoukankan      html  css  js  c++  java
  • Bellman-Ford算法

    Bellman-Ford算法是一种单源最短路算法,允许图中有负边权。Bellman-Ford算法的效率相对较低,但是很容易编写,也很好理解。比较流行的SPFA算法其实就是他的队列优化。Bellman-Ford算法的流程大体是这样,先将源点的最短路设置为0,将其他结点的最短路设置为inf,然后进行n-1次迭代,每次检查每条边进行松弛操作,这样就得到了其他结点的最短路。而且可以检查是否存在负环,若n次迭代仍然可以进行松弛操作,则说明存在负环。不难看出时间复杂度是O(nm)的。怎么理解Bellman-Ford算法呢?不妨想想一棵最短路径树,根是源点,叶子结点是图中其他结点,叶子结点到根节点的路径就是其他结点的最短路。虽然这棵树一开始我们并不知道什么样子,但他是客观存在的。而Bellman-Ford算法就是逐层构造这棵最短路树,假设处理到了第i层,那么第i-1层已经处理完毕,那么扫描每一条边,看是否可以松弛,一定可以由第i-1层扩展到第i层。如果把源点看做第0层,那么这棵树最多有n-1层,因此迭代n-1次一定可以得到这棵最短路树(如果存在的话),那么如果第n次仍然可以进行松弛操作,说明不存在最短路(存在负环)。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<cstring>
     4 const int inf=0x3f3f3f3f;
     5 int n,m,s,d[maxn];
     6 struct edge {
     7     int u,v,w;
     8     edge(int u=0,int v=0,int w=-1):u(u),v(v),w(w) {}
     9 } E[maxm];
    10 bool bellman() {
    11     memset(d,inf,sizeof(d));
    12     d[s]=0;
    13     for(int i=1;i<=n;++i) //循环检查n次,正常情况下最多迭代n-1次,第n次用于判断是否存在最短路
    14         for(int i=1;i<=m;++i) {
    15             int u=E[i].u,v=E[i].v,w=E[i].w;
    16             if(d[v]>d[u]+w) { //松弛操作
    17                 if(i==n) return false;
    18                 else d[v]=d[u]+w;
    19             }
    20         }
    21     return true;
    22 }
    23 int main() {
    24     scanf("%d%d%d",&n,&m,&s);
    25     int u,v,w;
    26     for(int i=1;i<=m;++i) {
    27         scanf("%d%d%d",&u,&v,&w);
    28         E[i]=edge(u,v,w);
    29     }
    30     if(!bellman()) printf("Wrong!");
    31     else for(int i=1;i<=n;++i) {
    32         if(i!=1) putchar(' ');
    33         printf("%d",d[i]);
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    龙年新作:水印文字添加工具源码摘要
    C语言关键字 浪里白条:goto
    继续聊WPF——自定义命令
    CSS3新的鼠标样式介绍
    C语言深入理解 常量与变量
    XCode 4 不能运行的解决办法
    Runtime专题:详解IOS开发应用之并发Dispatch Queues
    C语言关键字 乱世枭雄:static与extern
    一步步带你做vue后台管理框架(一)——介绍框架
    怎么在谷歌浏览器中安装.crx扩展名的离线Chrome插件?
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9513642.html
Copyright © 2011-2022 走看看