SPFA算法
  求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm 最短路径快速算法-SPFA算法是西南交通大学段凡丁于1994年发表的。
  适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点。
  算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

因为SPFA没有向迪杰斯塔拉算法那样,寻找dist[]的最小值,所以重复入队,更新dis[]的最小值,因为这个点本身dis[]的变化,会影响到与之邻接的点,所以要重复入队。
标程一:
const int INF = 999999;
int  map[MAXN][MAXN]; //map[i,j]为初始输入的ij的距离,未知的map[i,j]=INF;
int  dis[MAXN];//源点Si的最短路
char vst[MAXN];//是否在队列中的标记
int      Q[MAXN];//队列
// 参数n表示结点数,s表示源点
int SPFA(int n, int s)
{  int i, pri, end, p, t; // pri是队列头结点,end是队列尾结点
    memset(vst, 0, sizeof(vst));//初始化
    for(int i=0; i<</b>MAXN; ++i)
        Q[i] = 0;//初始化队列为空
    for (i=0; i<</b>n; i++)
        dis[i] = INF;//初始化源点到I的值为最大值
    dis[s] = 0;//源点为0
    vst[s] = 1;//标记为已入队
Q[0] = s;//源点入队
pri = 0; end = 1;//队首队尾赋值
    while (pri <</b> end)
    {
        p = Q[pri];//取队首元素
        for (i=0; i<</b>n; ++i) //更新dis
        { if (dis[p]+map[p][i] <</b> dis[i])
            {  dis[i] = dis[p]+map[p][i];
                if (!vst[i])     //未在队列中
                {  Q[end++] = i;
                   vst[i] = 1;
                }
            }
        }
        vst[p] = 0;   // 置出队的点为未标记
        pri++;
    }
    return 1;
}
标程二:
int num[999999]; //记录入队次数  
void spfa(int s)  //  初始结点s,即为起点,若目标结点t,则输出dict[t]。
{   init_data(s);
    int head = 0, tail = 1;  
    int path[Max];  //  可增加一个path[]数组来记录最后s到t的路径。
    queue[0] = s; //que.push(s);  
    dict[s] = 0;
    while (tail > head)//(!que.empty())
 
    { int u = queue[head];//int u=que.front();   //que.pop();
        vis[u] = true;  
        for (i = 1; i <= n; i ++)
        { if (dict[i] > dict[u] + edge[u][i])
            {  dict[i] = dict[u] + edge[u][i];
               path[i] = u;  
               num[i]++
               if(num[i]>=n) return 1;//判断是否有负权值……
               if (!vis[i])  //  对以前没有访问过的顶点,加入队列中。
                {  vis[i] = true;
                   queue[tail] = i;// que.push(i);
                   tail ++;                        
                }
             }
         }
         vis[u] = false;  //  记得把出队列的顶点的vis[]置为false。
        head ++;  
    }
}
判断负权回路 num[i]>=n的原因,即使所有的点更新都会让i入队的话,才只有n-1次,这时一定是最小值了,入队n次,一定有负权回路

[转]关于一些SPFA的标程的更多相关文章

  1. [求助][SPOJ MARIOGAM]-高斯消元(内含标程,数据等)

    小蒟蒻开始做概率的题之后,遇到了这道题,然而,他发现自己的程序调试了无数次也无法通过,系统总是返回令人伤心的WA, 于是,他决定把这一天半的时间收集到的资料放在网上, 寻求大家的帮助, 也可以节省后来 ...

  2. hdu6435 Problem J. CSGO标程讲解以及改正标程的一个错误(本来第一个样例过不了2333) 以及 poj2926 五维曼哈顿距离模板

    比赛的时候抄poj2926的模板,但改不来啊orz #include <iostream> #include <cstdio> #include <cstring> ...

  3. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  4. 王学长的LCT标程

    善良的王学长竟然亲自打了一遍QAQ好感动QAQ #include<iostream> #include<cstdio> #include<cmath> #inclu ...

  5. BJOI2019Day1 数据&标程&题解

    链接: https://pan.baidu.com/s/16L5GHvo9WtY20sZoqjuQNQ 提取码: 3iur

  6. HDU4631(标程代码)

    /*将x从小到大排序,每次插入一个点,直接找比这个点的x大的第一个,然后从这个开始向两边找 ,找点的下标用多重容器实现*/ #include<stdio.h> #include<st ...

  7. 【CQ18高一暑假前挑战赛5】标程

    [A:暴力] #include<bits/stdc++.h> using namespace std; ; int a[maxn],vis[maxn],N,M; int main() { ...

  8. 【CQ18高一暑假前挑战赛4】标程

    [二分或者STL] 二分: #include<bits/stdc++.h> using namespace std; ; int a[maxn]; int main() { ,pos; s ...

  9. 【CQ18高一暑假前挑战赛3.5】标程

    [A:快速幂相关] #include<bits/stdc++.h> using namespace std; int qpow(int a,int x){ a%=;; while(x){ ...

随机推荐

  1. E 定向 牛客练习赛25

    tarjan 父节点和子节点 #include <cstdio> #include <cstdlib> #include <cmath> #include < ...

  2. zabbix server安装(二)

    https://mp.weixin.qq.com/s/ogaqiX4vhtGLepuNf-1ItA zabbix依赖LNMP或LAMP,下面讲解LNMP安装到zabbix web页面的访问. 一.ng ...

  3. Centos7.4+openvpn-2.4.4+easy-rsa-3.0物理机安装教程

    完整CentOS搭建OpenVPN服务环境图文教程 大福技术 关注 2016.02.17 09:28* 字数 3017 阅读 34000评论 18喜欢 21赞赏 3 对于OpenVPN环境有什么用途老 ...

  4. 图解MySQL 内连接、外连接

    2.内连接(INNER JOIN)内连接(INNER JOIN):有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行.(所谓的链接表就是数据库在做查询形成的中间表).例如:下面的语句3 ...

  5. Kafka 温故(二):Kafka的基本概念和结构

    一.Kafka中的核心概念 Producer: 特指消息的生产者Consumer :特指消息的消费者Consumer Group :消费者组,可以并行消费Topic中partition的消息Broke ...

  6. [转载]Frontend Knowledge Structure

    https://github.com/JacksonTian/fks http://code.csdn.net/news/2819224 本文为大家整理了一系列关于JavaScript的常用工具,包括 ...

  7. linux sftp安装【转】

    工具:虚拟机:VMware Workstation Pro.操作系统:CentOS-6.4-x86_64-minimal.终端模拟器:Xshell 5 .ftp:filezilla 一.让虚拟机联网 ...

  8. innobackupex不停库的数据备份并恢复到别的服务器上【转】

    1.innobackupex原理: 备份原理 1).首先会开启一个后台检测进程,实时检测myql redo的变化,一旦发现redo中有新日志写入,立即将日志记入后台日志文件xtrabackup_log ...

  9. Kali Linux没有声音的解决方法

    Kali Linux系统默认状态下,root用户是无法使用声卡的,也就没有声音.启用的方法如下:         (1)在终端执行命令:systemctl --user enable pulseaud ...

  10. java虚拟机规范(se8)——java虚拟机结构(三)

    2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是 ...