SPFA算法求单源最短路径

来源:互联网 发布:评论系统源码 编辑:程序博客网 时间:2024/05/22 03:51

SPFA算法求单源最短路径

  • 算法简介:

    SPFA算法是应用于有向图上的一种算法,常用于求出从源点s到其它所有点的最短路径。相对于Dijkstra的O(n^2)的复杂度,SPFA的复杂度仅仅与边有关,为O(KE),其中E为该图的边数,且可以证明K < 2,故对于稀疏图来说,SPFA相较于Dijkstra要快上不少。

  • 算法思想:

    SPFA算法是基于广搜的思想实现它O(KE)的复杂度的。这里我用vector存放从每个点到其它点的可能路径,这种基于邻接表的思想相对于邻接矩阵省下了不少空间。最开始先将源点s放入队列,将表示点与源点之间的距离最小值的数组d[s]设为0,其余点的的距离设为inf,同时标记数组p[s]设为1。对于现在的节点的可能路径上能到达的每一个节点,我们进行relax松弛操作,对于每一次所能到达的节点更新最优值,同时当当前节点没有入队的时候,将它放入队列并做好标记。当队列为空的时候,则已经找到最优值,这时候统计d数组即为所求。

  • 代码实现:

    #include<iostream>  #include<cstdio>  #include<vector>  #include<map>  #include<cmath>  #include<cstring>  #include<algorithm>  const int maxn=10000+10, inf=0x3f3f3f3f;  using namespace std;  struct node{int to, z;};  int p[maxn],d[maxn];  vector<node>e[maxn];  int q[maxn*100];  int main(){  int k,m,n,s;      scanf("%d%d%d", &n, &m, &s); for(register int i = 1; i <= m; i++){      int x, y, z;      scanf("%d%d%d", &x, &y, &z);      node t;      t.to = y;    t.z = z;      e[x].push_back(t);  }  for(register int i = 1; i <= n; i++)    d[i] = inf;  d[s] = 0;  q[1] = s;p[s] = 1;  int f = 0, l = 1;  while(f < l){      f++;      int x = q[f];      for(register int i = 0; i < e[x].size(); i++){          int u = e[x][i].to, v = e[x][i].z;          if(d[u] > d[x]+v){              d[u] = d[x] + v;              if(!p[u]){                  q[++l] = u;                  p[u] = 1;              }                     }             }      p[x] = 0;   }  for(register int i = 1; i <= n; i++)      if(d[i] < inf)        printf("%d ",d[i]);      else         printf("2147483647 ");  return 0;  }