zoukankan      html  css  js  c++  java
  • 图论:最短路-SPFA

    该算法由Bellman-Ford算法演变过来,首先介绍一下Bellman-Ford算法

    最短路最多经过n-1个点,可以用n-1轮松弛操作来得到

    for(int i=0;i<n;i++)
        d[i]=INF;
    d[0]=0;
    for(int k=0;k<n-1;k++)
    for(int i=0;i<m;i++)  //检查每条边 
    {
        int x=u[i];
        int y=v[i];
        if(d[x]<INF)
            d[y]=min(d[y],d[x]+w[i]);
    } 

    当然这个算法我没有实际应用过,而是一直在用它的优化算法,利用队列代替前面的循环检查

    SPFA最坏时间复杂度仍然为O(nm),但是有人分析其时间复杂度为O(km),k为每个点入队次数,正确性未知

    SPFA和Bellman-Ford都可以检测负环但是只有后者可以输出负环

    下面给出邻接表实现的SPFA算法,可以求出单源最短路。

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int maxn=10005;
     5 const int maxm=500005;
     6 const int INF=0x7fffffff;
     7 //
     8 int n,m,s;
     9 //
    10 int g[maxn];
    11 struct point
    12 {
    13     int t,w,next;
    14 }e[maxm];
    15 int d[maxn];
    16 //
    17 int tot=0;
    18 void addedge(int a,int b,int c)
    19 {
    20     tot++;
    21     e[tot].t=b;
    22     e[tot].w=c;
    23     e[tot].next=g[a];
    24     g[a]=tot;
    25 }
    26 //
    27 int q[maxn];
    28 bool v[maxn];
    29 void spfa(int x0)
    30 {
    31     for(int i=1;i<=n;i++)
    32     d[i]=(i==x0?0:INF);
    33     int h=0,t=1;
    34     q[t]=x0;
    35     while(h!=t)
    36     {
    37         h=h%maxn+1;
    38         int x=q[h];
    39         v[x]=false;
    40         for(int tmp=g[x];tmp;tmp=e[tmp].next)
    41         {
    42             if(d[e[tmp].t]>d[x]+e[tmp].w)
    43             {
    44                 d[e[tmp].t]=d[x]+e[tmp].w;
    45                 if(!v[e[tmp].t])
    46                 {
    47                     v[e[tmp].t]=true;
    48                     t=t%maxn+1;
    49                     q[t]=e[tmp].t;
    50                 }
    51             }
    52         }
    53     }
    54 }
    55 int main()
    56 {
    57     cin>>n>>m>>s;
    58     for(int i=1;i<=m;i++)
    59     {
    60         int x,y,z;
    61         cin>>x>>y>>z;
    62         addedge(x,y,z);
    63     }
    64     spfa(s);
    65     for(int i=1;i<=n;i++)
    66         cout<<d[i]<<" ";
    67     return 0;
    68 }
  • 相关阅读:
    Python十大经典算法之选择排序
    在js中修改样式带 !important 的样式
    vscode 使用 ejs 语法有红色错误提示线
    mysql 报 'Host ‘XXXXXX’ is blocked because of many connection errors'
    字符编码
    Canal.adapter报错
    Windows 域控配置时间同步
    Docker清理日志脚本
    Docker快速部署clickhouse
    Windows批处理一键添加hosts文件
  • 原文地址:https://www.cnblogs.com/aininot260/p/9272894.html
Copyright © 2011-2022 走看看