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]为初始输入的i到j的距离,未知的map[i,j]=INF;
int  dis[MAXN];//源点S到i的最短路
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. node.js原生后台进阶(一)

    后台对于我们前端来说可能真的有点陌生,下面我来理清一下思绪吧. 一个基本的后台要求有如下功能: 1.与前端的数据交互 2.操作数据库(增删改查) 3.操作服务器文件(也大概是增删改查) 本次我们先讨论 ...

  2. C语言复习---获取矩阵的对角和

    #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX 5 int main() ...

  3. hdu 6166 Senior Pan

    http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这k个特殊点两两之间的最短路 二进制分组 枚举一位二进制位 这一 ...

  4. php设计模式之注册树模式

    什么是注册树模式?[全局共享和交换对象] 注册树模式当然也叫注册模式,注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法.   这让我想起了小时候买糖 ...

  5. 【转载】RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  6. iOS-Socket编程体验

    CHENYILONG Blog Socket编程体验 Socket编程体验  技术博客http://www.cnblogs.com/ChenYilong/新浪微博http://weibo.com/lu ...

  7. python技巧 使用值来排序一个字典

    In [8]: a={'x':11,'y':22,'c':4} In [9]: import operator In [10]: sorted(a.items(),key=operator.itemg ...

  8. HTML+CSS写下拉菜单

    今天学习了使用HTML+CSS实现下拉菜单效果,在这个例子中,我学到了如下知识点: 设置背景图片(background-image.background-size) 如何让无序列表横向显示(float ...

  9. thinkphp5学习总结!

    数据库操作之原生sql操作 <?php namespace app\index\controller; use think\Db; class Index { public function i ...

  10. Linux环境下段错误的产生原因及调试方法小结【转】

    转自:http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...