3.1最短路之单源最短路(SPFA)

松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离。

邻接表:表示与一个点联通的所有路。

如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于0,

就说这条路是一个负权回路。

回归正题,SPFA是bellman-ford的一种改进算法,由1994年西安交通大学段凡丁提出。它无法处理带有负环的图,判断方法:如果某个点进入队列的次数超过N次则存在负环。

SPFA的两种写法,bfs和dfs,bfs判别负环不稳定,相当于限深度搜索,但是设置得好的话还是没问题的,dfs的话判断负环很快(我也看不懂,推介宽艘)。

int n;        //表示n个点,从1到n标号
int s,t;        //s为源点,t为终点
int d[N];    //d[i]表示源点s到点i的最短路
bool vis[N];    //vis[i]=1表示点i在队列中
queue<int>q;    //队列
int spfa_dfs(int u)
{
    vis[u]=true;
    ;k=e[k].next)
    {
        int v=e[k].v,w=e[k].w;
        if(d[v]>d[u]+w)
        {
            d[v]=d[u]+w;
            if(vis[v]) return true;
            else if(spfa_dfs(v)) return true;
        }
    }
    vis[u]=false;
}

Bfs版:

/*

给出一个有N个节点,M条边的带权有向图.判断这个有向图中是否存在负权回路.

如果存在负权回路, 只输出一行-1;

如果不存在负权回路,再求出一个点S到每个点的最短路的长度.

约定:S到S的距离为0,如果S与这个点不连通,则输出NoPath.

点数N,边数M,源点S;以下M行,每行三个整数a,b,c表示点a,b之间连有一条边,权值为c

如果存在负权环,只输出一行-1,否则按以下格式输出共N行,第i行描述S点到点i的最短路:

如果S与i不连通,输出NoPath;如果i=S,输出0;其他情况输出S到i的最短路的长度

INPUT:

6 8 1

1 3 4

1 2 6

3 4 -7

6 4 2

2 4 5

3 6 3

4 5 1

3 5 4

OUTPUT:

0 6 4 -3 -2 7*/

#include<cstdio>
using namespace std;
struct point
{
    int ans;  //距离源点的最短距离
    int lson; //最后的儿子
    int p;    //被放进序列(list)的次数统计
    int v;    //是否在序列(list)中
}a[];
struct road
{
    int x,y,c,g;//起点、终点、长度和哥哥
}b[];
void BuildRoad(void);
void ShortRoad(int);
],n,m,s,k;//路的数量
bool bo;
int main()
{
    scanf("%d %d %d",&n,&m,&s);
    k=;
    ;i<=n;i++) a[i].lson=;//放在建路之前
    ;i<=m;i++) BuildRoad();
    bo=true;
    ;i<=n;i++)
    {
        ShortRoad(i);//寻找负权回路
        if(bo==false)
        {
            printf("-1");
            ;
        }
    }
    ShortRoad(s);
    ;i<=n;i++)
        ) printf("NoPath\n");
        else printf("%d\n",a[i].ans);
}

void BuildRoad(void)
{
    int x,y,c;
    scanf("%d %d %d",&x,&y,&c);
    k++;
    b[k].x=x;
    b[k].y=y;
    b[k].c=c;
    b[k].g=a[x].lson;
    a[x].lson=k;
}

void ShortRoad(int st)
{
    ;i<=n;i++)
    {
        a[i].ans=;
        a[i].p=;a[i].v=;
    }
    a[st].ans=; a[st].p=;
    a[st].v=]=st;
    //放入序列中
    ,wei=;
    ) wei=;//循环数组
    while(tou!=wei)
    {
        int x=list[tou];
        ;i=b[i].g)
        {
            int y=b[i].y;
            if(a[y].ans>a[x].ans+b[i].c)
            {
                a[y].ans=a[x].ans+b[i].c;//松弛
                if(a[y].v==false)//如果还没有放入
                {
                    a[y].p++;
                    if(a[y].p>n)
                    {
                        bo=false;return;
                    }
                    a[y].v=;list[wei++]=y;
                    ) wei=;
                }
            }
        }
       a[x].v=false; tou++;
       ) tou=;
    }
}

进阶:

【宽搜高级利用】最后的战犯
【两个人,一步一步。。。。】
 
最短路变例
【坐标计算】
 
【宽搜变例】【按照一定次序】密室逃脱
【bfs+dfs】
 
[JSOI2008]星球大战StarWar
【并查集+最短路】

模板C++ 03图论算法 1最短路之单源最短路(SPFA)的更多相关文章

  1. 模板C++ 03图论算法 2最短路之全源最短路(Floyd)

    3.2最短路之全源最短路(Floyd) 这个算法用于求所有点对的最短距离.比调用n次SPFA的优点在于代码简单,时间复杂度为O(n^3).[无法计算含有负环的图] 依次扫描每一点(k),并以该点作为中 ...

  2. Fire-Fighting Hero(多源最短路和单源最短路)

    题:https://nanti.jisuanke.com/t/41349 分析:对于hero来说,走单源最短路,然后遍历dis数组中的最大值即可找到,对于消防员来说,走多源最短路,只需要建个超级起点连 ...

  3. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  4. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

  5. 图论-单源最短路-SPFA算法

    有关概念: 最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径 SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径) 约定:图中不存在负权环,用邻接表 ...

  6. 2018/1/28 每日一学 单源最短路的SPFA算法以及其他三大最短路算法比较总结

    刚刚AC的pj普及组第四题就是一种单源最短路. 我们知道当一个图存在负权边时像Dijkstra等算法便无法实现: 而Bellman-Ford算法的复杂度又过高O(V*E),SPFA算法便派上用场了. ...

  7. 单源最短路模板(dijkstra)

    单源最短路(dijkstra算法及堆优化) 弱化版题目链接 n^2 dijkstra模板 #include<iostream> #include<cstdio> #includ ...

  8. 用scheme语言实现SPFA算法(单源最短路)

    最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇. 这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法.当时的我,花了一整天时间,学 ...

  9. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

随机推荐

  1. js中的IP格式正则匹配校验详解~

    IPV4的格式为x:y:z:w,其中{x,y,z,w}属于{0~255}的正整数: 下面是其校验的正则表达式: function isIP(ip) { var re =  /^(\d{1,2}|1\d ...

  2. HTML、CSS、JS 样式

    把一个数组(一维或二维等)的内容转化为对应的字符串.相当于把print_r($array)显示出来的内容赋值给一个变量.$data= array('hello',',','world','!'); $ ...

  3. ajax发送异步请求

    一:得到XMLHttpRequest对象 ajax其实只需要学习XMLHttpRequest一个对象 大多数浏览器都支持: var xmlHttp = new XMLHttprequest(); IE ...

  4. AspNet.OData 协议概述

    1. 什么是OData? OData 全称 Open Data Protocol,字面理解为开放数据协议,是一个基于Http协议且API实现为Restful风格的协议标准,目前由微软支持大力推广,你可 ...

  5. 2017-4-26 winform tab和无边框窗体制作

    TabIndex-----------------------------------确定此控件将占用的Tab键顺序索引 Tabstop-------------------------------指 ...

  6. Websphere(was)与Weblogic部署EJB的注意项

    复杂的故事简单说,复杂的问题简单做. EJB容器 简介 本节讲解EJB项目在Weblogic和Was上的部署需要注意设置的一些内容.不同的中间件对EJB支持方式不一样,所以配置的原理也略有差异. 关键 ...

  7. Linux IO barrier

    I/O顺序问题是一个比较综合的问题,它涉及的层次比较多,从VFS page cache到I/O调度算法,从IO子系统到存储外设.而Linux I/O barrier就是其中重要的一部分. 可能很多人认 ...

  8. Oracle解析复杂json的方法

    问题背景: 当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的PLSQL脚本大多也只可以解析结构较单一的json串,对于结构复杂的json串还无法解析.如此 ...

  9. luogu 1521-求逆序对

    题意: 逆序对指在一个序列中ai>aj && i < j,也就是一前一后两个数,当大的在前面的时候即算一对. 题目求在一个由1-n组成的序列中逆序对为k的序列的个数. 出题 ...

  10. ST-3- Installing and Testing IUnit, Hamcrest and Eclemma

    一.安装JUnit和Hamcrest 1.首先从办公网上下载JUnit.jar和Hamcrest.jar,并且将其放入所进行的项目的bin目录下,我将其放入了triangle项目的bin目录下. 2. ...