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. python常用模块-调用系统命令模块(subprocess)

    python常用模块-调用系统命令模块(subprocess) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. subproces基本上就是为了取代os.system和os.spaw ...

  2. 快速了解yuv4:4:4 yuv4:2:2 yuv 4:1:1 yuv 4:2:0四种YUV格式区别

    四种YUV格式区别如下: 1.YUV  4:4:4抽样方式: Y: Y0 Y1 Y2 Y3 U: U0 U1 U2 U3 V: V0 V1 V2 V3 2.YUV   4:2:2抽样方式: Y   : ...

  3. select遍历list默认选中初始值

    <select id="userstatus" name="userstatus">         <c:forEach items=&qu ...

  4. 蓝桥杯 算法训练 单词接龙 _DFS_搜索 字符串比较

    单词接龙 问题描述  单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相 ...

  5. 用matplotlib制作的比较满意的蜡烛图

    用matplotlib制作的比较满意的蜡烛图 2D图形制作包, 功能强大, 习练了很久, 终于搞定了一个比较满意的脚本. 特点: 使用方面要非常简单 绘制出来的图要非常的满意, 具有如下的特点 时间和 ...

  6. git 学习小记

    话说 git 出了已经很久了,可是我一直没用过.其实也不是没用过,只不过在 github 上下载东西那根本就不是在用 git,只是单纯的HTTP下载而已.我们公司用的是 svn,所以我只会一点点svn ...

  7. js 正则学习小记之匹配字符串字面量

    今天看了第5章几个例子,有点收获,记录下来当作回顾也当作分享. 关于匹配字符串问题,有很多种类型,今天讨论 js 代码里的字符串匹配.(因为我想学完之后写个语法高亮练手,所以用js代码当作例子) va ...

  8. c# 防止sql注入对拼接sql脚本的各个参数处理

    调用方法:GameServerId = this.NoHtml(GameServerId);//GameServerId为一个拼接sql的参数 /// <summary> /// 过滤标记 ...

  9. ListView position

    在使用listview的时候,我们经常会在listview的监听事件中,例如OnItemClickListener(onItemClick)中,或listview的adapter中(getView.g ...

  10. C++笔试易错题集(持续更新)

    1.如下代码输出结果是什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include<stdio.h> char *myString() {     ...