• 初学SPFA


    SPFA 算法是Bellman-Ford算法的队列优化算法的别称,在国际上被称为“队列优化的Bellman-Ford算法”,仅在中国被称为SPFA算法。也就是说,这是Bell-man Ford的升级版(虽说本人也不会Bellman-Ford)。SPFA通常用于求含负权边的单源最短路径,以及判负权环。SPFA的时间复杂度一般为O(km)。但由于这种算法的过于玄学,当有人故意卡你时,可能会变成O(nm),所以请慎用。

    例题

    题目描述

    小Q非常喜欢在自己的国家旅行。小Q所在的国家有N座城市,分别编号为1~n,小Q所在的城市编号为1。小Q现在想知道从他所在的城市出发,到其他N-1个城市的最短路程分别是多少?

    输入

    第一行两个整数N,M(1<=n<=1000,1<=M<=100000),分别表示小Q所在的国家有N座城市以及城市间有M条单向道路。
    接下来M行,每行三个整数x,y,len(1<=x,y<=n,1<=len<=100000)表示从城市x去到城市y需要走len这么多路程。
    输入可能存在重边

    输入

    一共N-1行,每行一个整数,第i个整数表示小Q从城市1到城市(i+1)的最短路程。如果不能到达输出-1

    样例输出

    4 4
    1 2 3 2
    3 4 1 3
    2 2 4 1

    样例输出

     3
     2
     4

    代码实现

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    struct node
    {
        int ver;
        int edge;
        int next;
        
    };
    node d[100001];
    queue <int> q;
    int tot,x,y,z,dis[1001],head[100001],n,m;
    bool v[100001];
    void add(int a,int b,int c)//构建邻接表
    {
        tot++;
        d[tot].ver=y;
        d[tot].edge=z;
        d[tot].next=head[x];
        head[x]=tot;
    }
    void spfa()
    {
        memset(dis,0x3f3f3f,sizeof(dis));
        memset(v,false,sizeof(v));
        dis[1]=1;
        v[1]=true;
        q.push(1);
        while(q.size())//每次取出队头
        {
            int x=q.front();
            q.pop();
            v[x]=false;//扫描所有边
            for(int i=head[x];i;i=d[i].next)
            {
                int a=d[i].ver;
                int b=d[i].edge;
                if(dis[a]>dis[x]+b)//跟新最优解
                {
                    dis[a]=dis[x]+b;
                    if(!v[a])
                    {
                        q.push(a);
                        v[a]=true;
                    }
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        spfa();
        for(int i=2;i<=n;i++)
            printf("%d
    ",dis[i]-1);
        return 0;
    }

    本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!

    本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!

    本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!

  • 相关阅读:
    js在当前时间上加分钟数得到新的时间
    (转)@Autowired(required=false)注入注意的问题
    Java代替if和switch的方法(记录一下)
    windows下RocketMQ的安装部署
    RocketMQ在windows环境下的安装(转)
    简单说下二维数组
    JAVA-单例模式的几种实现方式
    (转)mybatis一级缓存二级缓存
    MySql安装后在服务管理器里边找不到MySql服务项的解决办法(win10)
    JAVA字符串的替换replace、replaceAll、replaceFirst的区别解析。
  • 原文地址:https://www.cnblogs.com/abcdhh/p/11383865.html
Copyright © 2020-2023  润新知