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. codeblocks调试

    1.Next instruction 逐指令 (有可能一行内有多条指令) (Alt+F7) Next line 逐行(有可能一条指令分成多行) (F7) Next instruction: -> ...

  2. pthread_detach

    http://blog.csdn.net/scanery/article/details/7241890   感谢作者! 近来发现 在线程函数第一行调用 pthread_detach(pthread_ ...

  3. eos交易同步过程和区块生产过程源码分析

    交易同步过程 1 通过命令cleos调用 cleos transfer ${from_account} ${to_account} ${quantity} 发起交易2 eos调用chain_plugi ...

  4. Git与GitHub学习笔记(二)提交的一些笔记

    1.合并分支的使用一定要切换到master分支上去合并:git merge company2.切换分支的时候一定要提交干净本地分支的代码,才可以切换分支,否则提示错误信息: 3.这时候我们做的就是提交 ...

  5. 流媒体技术学习笔记之(七)进阶教程OBS参数与清晰度流畅度的关系

    源码地址:https://github.com/Tinywan/PHP_Experience 很多主播问过OBS的参数到底什么影响画质,到底什么影响流畅度,那么本篇教程尽量用通俗的语言解释下一些重要参 ...

  6. AngularJS 启程三

    <!DOCTYPE html> <html lang="zh_CN"> <head> <title>字数小例子</title& ...

  7. sql查询语句优化

    http://www.cnblogs.com/dubing/archive/2011/12/09/2278090.html 最近公司来一个非常虎的dba  10几年的经验 这里就称之为蔡老师吧 在征得 ...

  8. Spring Mvc + Maven + yuicompressor 使用 profile 来压缩 javascript ,css 文件; (十)

    profile相关知识点: 在开发项目时,设想有以下场景: 你的Maven项目存放在一个远程代码库中(比如github),该项目需要访问数据库,你有两台电脑,一台是Linux,一台是Mac OS X, ...

  9. CSS absolute与relative不得不说的故事

    写在开篇: absolute说:“relative,我这辈子都不想看见你!” 为什么呢?它们明明那么相亲相爱,形影不离,这之中到底发生了什么不为人知的故事,竟然让absolute如此讨厌relativ ...

  10. 使用pt-table-checksum校验MySQL主从复制【转】

    pt-table-checksum是一个基于MySQL数据库主从架构在线数据一致性校验工具.其工作原理在主库上运行, 通过对同步的表在主从段执行checksum, 从而判断数据是否一致.在校验完毕时, ...