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 }
  • 相关阅读:
    使用云(BAE)实现android应用数据的远程存取(MySQL)
    VI键盘图
    IOS 6 UIActivityViewController详解 社交分享
    IOS 计算字体控件盖度, 设置粗体+阴影
    myeclipse中tomcat 7.0 关于64位与32位的冲突问题 ( tcnative1.dll )
    九度OJ 1001 A+B for Matrices
    网站10大常见安全漏洞及解决方案
    js网页如何获取手机屏幕宽度
    常用正则说明
    php中的线程、进程和并发区别
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9513642.html
Copyright © 2011-2022 走看看