• 【最短路径】 SPFA算法


      上一期介绍到了SPFA算法,只是一笔带过,这一期让我们详细的介绍一下SPFA。

    1 SPFA原理介绍

      SPFA算法和dijkstra算法特别像,总感觉自己讲的不行,同学说我的博客很辣鸡,推荐一个视频讲解,想看点这里,算法思路如下:

      1)和dijkstra一样初始化,定义一个dis[ ]数组,除了源点赋成0之外其它点都赋成正无穷,然后定义一个队列q。

      2)把队列q的队首元素取出,标志为不在队中,将其作为中继点对这个队首元素的所有出边进行松弛操作(不知道松弛操作请看这里),修改完dis值后,判断每一个修改过dis值的元素是否在队列q中,如果不在,就放入队尾;然后判断这个数入队的次数,如果大于n(n为点的个数),那就说明出现了负权回路,算法结束,否则继续。

      3)不断循环,直到队列为空。

    2 实现过程中的一些问题

    •   question:怎么标志出队?

      answer:可以定义一个vis[ ]数组,最开始全部为0,表示都不在队列中,每入队一个元素x,就把vis[x]赋成1,每出队一个元素就赋值成0。

    •   question:怎么判断一个数入队次数?

      answer:可以定义一个num[ ]数组,每入队一个元素x,就num[x]++;这个可以不写,因为题目一般不会出现负权回路。

    •   question:怎么判断队列为空?

      answer:最流行的写法是while(!q.empty()),但是不太好理解,我一般会写成while(s.size()),和前一句意思相同。

    3 图解演示

      //这个图解做了一上午,可能讲的不好,不喜勿喷

    4 代码奉上:

     1 void SPFA()
     2 {
     3     for(int i=1;i<=n;i++)
     4     dis[i]=inf;
     5     queue<int>q;
     6     q.push(1);vis[1]=1;dis[1]=0;
     7     while(q.size())
     8     {
     9         x=q.front();q.pop();vis[x]=0;
    10         for(int i=head[x];i;i=a[i].next)
    11         {
    12             int s=a[i].to;
    13             if(dis[s]>dis[x]+a[i].cost)
    14             {
    15                 dis[s]=dis[x]+a[i].cost;
    16                 if(vis[s]==0)
    17                 {
    18                     vis[s]=1;
    19                     q.push(s);
    20                 }
    21             }
    22         }
    23     }
    24 }

     5 算法优化

      新更博客:SPFA算法优化

  • 相关阅读:
    Meterpreter核心命令
    bugku ctf 杂项 旋转跳跃 (熟悉的声音中貌似又隐藏着啥,key:syclovergeek)
    bugku 神秘的文件
    代码审计
    “百度杯”CTF比赛 九月场 类型:Web 题目名称:SQLi ---不需要逗号的注入技巧
    热烈祝贺北亚获批电子数据司法鉴定执业资格!
    硬盘有坏道的表现和避免硬盘坏道的方法
    如何应对eva存储崩溃的情况?
    linux系统数据恢复过程
    DELL EqualLogic PS6100恢复数据原理概述
  • 原文地址:https://www.cnblogs.com/TFLS-gzr/p/10387463.html
Copyright © 2020-2023  润新知