zoukankan      html  css  js  c++  java
  • 最短路之--spfa

    其实 提到最短路 应该是先讲Dijkstra 但它的未进行优先队列优化的普通版本与昨天所讲的Prim实在太像了. 所以决定延后几天再讲吧.

    今天晚上 去西厂听老蔡和XX 去讲他们的心理路程(找不到好的词语来修饰。。。。)  还是有很多感触的 差距还是很大的. 但往好了想 毕竟我也才大一 是吧? 还来得及。。。

    打完这段话 突然想到了 自欺欺人 这4个字。。。

    好了 切回正题。  

    今天 我们讲的spfa是bellman-ford的优化 关于这个算法最重要的事 应该是它是由我们西南交通大学的段丁凡 提出的..  当时看到这个 还是很让人振奋的.

    它是通过队列进行优化实现的   现在我们就具体来讲讲它的优化实现方式与过程吧

    初始化的时候 将源点加入队列 每次从队列中取出一个元素 并将所有与它相邻的点进行松弛操作 若某个相邻的点松弛成功 则将其入队 直到队列中无任何元素为止 over .

    可能 你会有疑惑 为什么 松弛成功的点 才能入队呢?

    很简单 你可以这样想 如果松弛不成功 那么它与源点的相对距离没有缩减 那么假如有条路径 源点-该点-目标点  是没必要去尝试的 因为我并没有松弛成功 距离没有缩减

     这边有必要提下 松弛操作  这个会在我们很多关于图论的算法中涉及到. 譬如上次提过的Prim就运用了它.

    松弛--往简单了说 就是刷新该点与源点的最短距离 可能这个解释太过简单了  如果你想更详细的了解 自行百度吧。。

    dist[i]表示源点到 I 的当前最短距离

    linker[i]表示源点到I的当前最短路径中I点之前的一个点的编号

    开始时 dist[i]全部初始化为+∞  除离自身dist[S]=0 ;

    linker[i]全部初始化为S

    每次的迭代操作  取出队首V 依次枚举从V出发的边 V->U

    判断 dist[v]+map[u][v] 与 dist[u] 的大小关系

    若松弛成功 即离源点的相对距离缩短 并且若u不在队列中 就将u入队 放入队尾

    这样 重复操作 持续迭代 直至队列为空 即所有点到S的最短路距离  就这样都确定了

    特别要提一点 其实spfa并不是我们所讲述的那么好  它是效率不稳定的  一般情况下 我们用Dijkstra就可以解决 遇到任意2点间距离的话 可以用floyd算法 这些我们都会在

    后面的随笔中涉及到    

    接下来 给出它的模板

     1 void spfa()
     2 {
     3     memset( vis, false , sizeof(vis) );
     4     queue<int>qe;
     5     for(int i=0;i<n;i++)
     6     {
     7         dist[i]=inf;
     8     }
     9     dist[begin]=0;
    10     vis[begin]=true;
    11     qe.push(begin);
    12     while( !qe.empty() )
    13     {
    14         int temp=qe.front();
    15         qe.pop();
    16         for(int i=0;i<n;i++)
    17         {
    18             if( dist[temp] + map[temp][i] < dist[i] )
    19             {
    20                 dist[i]= dist[temp]+map[temp][i];
    21                 if( !vis[i] )
    22                 {
    23                     qe.push(i);
    24                     vis[i]=true;
    25                 }
    26             }
    27         }
    28         vis[temp]=false;
    29     }
    30 }
    View Code

    这里 我并没有给它加以注释 因为我知道 如果你和我一样是初学者 当第一次看到这段代码的时候 即使看了我上面那段 又臭又长的叙述 肯定还是有很多疑惑的  我还是希望

    你能去看更加详细的解释 加上 自己的思索 所以 我这边不想加以注释

    spfa是我很喜欢的算法  感觉名字很cool。。。。

    写完 恰好次日凌晨...

    just follow your heart
  • 相关阅读:
    mvn tomcat7:help的14个命令
    leetcode Next Permutation
    leetcode Permutation
    java HashMap
    单链表反转(递归和非递归) (Java)
    java数据类型
    Multiply Strings 大数相乘 java
    SQL中如何使用UPDATE语句进行联表更新(转)
    循环建立索引
    js 跨域访问
  • 原文地址:https://www.cnblogs.com/radical/p/3665269.html
Copyright © 2011-2022 走看看