SPFA算法

算法思想:
1) 三角形中的性质:同一三角形内两边之和大于第三边。

2)由上面那一条性质,我们可以想出一个方法来更新源点到其他点的最短的路径:用中间节点k松弛u->k->v,来更新u->v的最短路径(思想和Floy算法相似),也就是说,我们实际上每次都是在判断这条路径符不符合三角形不等式dis[v]<dis[u]+dis[u->v],若不符合,我们就将原先的路径松弛为现在的路径,使得现在的路径满足三角形不等式。

3)但是为什么松弛后要将终点入队呢?SPFA的过程是BFS,它是不停扩展节点的。而当我们更新了这一条路径,那么可能会出现基于这一条路径的新路,我们需要判断原路与新路是否满足三角形不等式。即:有了新的最短路,就用它再去更新与他相连的点的最短路。

实现及细节
1)用visit[ ]数组来维护已经入队的顶点;并注意:出队时消除标记

2)用队列来维护松弛过的顶点

3)用链式前向星存图(连接?)

4)dis[ ]数组要初始化为INF;

上代码:

struct edge{int next,to,w;}e[10000];
bool visit[10000];
dis[10000];
int head[1005]={0};
int cnt;
void init(){ memset(dis,127,sizeof(dis));memset(visit,false,sizeof(visit));}
inline void add(int u,int v,int w)///无向边,所以加两次,若是有向边只需要加一次;
{e[++cnt].w=w;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[++cnt].w=w;e[cnt].to=u;e[cnt].next=head[v];head[v]=cnt;
}
void SPFA()
{init();dis[1]=0;queue<int>q;///存的是松弛过的顶点q.push(1);visit[1]=true;while(!q.empty()){int u=q.front();///获取顶点/边的起点q.pop();visit[u]=false;///别忘记:出队了,消除标记for(int E=head[u];E;E=e[E].next)///遍历以u为起点的所有边{int v=e[E].to;///边E的终点vif(dis[v]>dis[u]+e[E].w)///顶点v可以被边E松弛{dis[v]=dis[u]+e[E].w;if(visit[v]==false)///且v没在队里{visit[v]=true;q.push(v);}}}}
}

例题 黑暗城堡

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
const int mod=2147483647;bool visit[1005]={false};
ll dis[1005],num[1005]={0};///距离数组,num[i]代表起点i符合条件的个数
void init(){ memset(dis,127,sizeof(dis));memset(visit,false,sizeof(visit));}struct edge
{int to,next,w;
}e[1000005];///边
int head[1005]={0};
int cnt;inline void add(int u,int v,int w)///无向边,所以加两次
{e[++cnt].w=w;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[++cnt].w=w;e[cnt].to=u;e[cnt].next=head[v];head[v]=cnt;
}void SPFA()
{init();dis[1]=0;queue<int>q;///存的是松弛过的顶点q.push(1);visit[1]=true;while(!q.empty()){int u=q.front();///获取顶点/边的起点q.pop();visit[u]=false;///出队了,消除标记for(int E=head[u];E;E=e[E].next)///遍历以u为起点的所有边{int v=e[E].to;///边E的终点vif(dis[v]>dis[u]+e[E].w)///顶点v可以被边E松弛{dis[v]=dis[u]+e[E].w;if(visit[v]==false)///且v没在队里{visit[v]=true;q.push(v);}}}}
}int main()
{ll ans=1;int n,m;cin>>n>>m;for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;add(u,v,w);}SPFA();for(int i=1;i<=n;i++)///遍历所有顶点{for(int E=head[i];E;E=e[E].next)///遍历i为起点的所有边{int v=e[E].to;if(dis[i]+e[E].w==dis[v])///符合题目条件S[i]=D[i],D[i]=dis[i],S[i]=dis[i]+e[E].wnum[v]++;}}for(int i=2;i<=n;i++) ans*=num[i],ans%=mod;///排列组合的乘法原理cout <<ans<< endl;return 0;
}

SPFA算法+例题 :问题 A: 黑暗城堡相关推荐

  1. 图论-最短路径--3、SPFA算法O(kE)

    SPFA算法O(kE) 主要思想是:     初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束.     这个算 ...

  2. 信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数

    1486:黑暗城堡 [题目描述] 知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di为如果所有的通道都被修建,第 i 号房间与第 1 ...

  3. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

    这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...

  4. 一本通 P1486 【黑暗城堡】

    题库 :一本通 题号 :1486 题目 :黑暗城堡 link :http://ybt.ssoier.cn:8088/problem_show.php?pid=1486 思路 :这道题既然要求使加入生成 ...

  5. 最短路算法 :Bellman-ford算法 Dijkstra算法 floyd算法 SPFA算法 详解

     本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并不低所以,本文的代码 存图只 ...

  6. Bellman-ford和SPFA算法

    目录 一.前言 二.Bellman-ford算法 1.算法思想 2.算法复杂度 3.判断负圈 4.出差(2022第十三届国赛,lanqiaoOJ题号2194) 三.SPFA算法:改进的Bellman- ...

  7. SPFA算法求固定点到其它点 最短 最长 路程问题

    点击:理解请参考 例题:https://www.luogu.com.cn/problem/P1807 如果求最短路径 :vis[nex] = min(vis[nex], vis[now]+B[now] ...

  8. 第十九章 Bellman-Ford算法(由SPFA算法逆推BF,独特解读,超级详细)

    第十九章 Bellman-Ford算法 一.SPFA算法回顾: 二.Bellman-Ford算法 1.算法推导: 1.算法模板: 三.例题: 1.问题: 2.模板: 3.分析: 一.SPFA算法回顾: ...

  9. 最短路径算法——SPFA算法

    在家的这几天效率还是蛮低的,总是有其他的事情耽搁,然后最近就在做搜索题,然后做了两个搜索关于最短路径的,点数少的时候之前学的佛洛依德还能派上点用处,可以点数过1000之后就容易超时了,然后看他们的题解 ...

最新文章

  1. 判别测试字段怎么算它的位数_心理测试 | 成人依恋量表-亲密关系经历量表ECR...
  2. python 中求最大值问题_Python中用max()方法求最大值的介绍
  3. Extjs弹窗-简单文本编辑框-Ext.Msg.show
  4. @Modules( ... ) 多个包路径问题
  5. 杭州之行--记杭电网新恩普杯程序设计邀请赛
  6. python和java哪个好学-Python和Java对比,全面解读哪个语言最赚钱,前景最好?
  7. 成都专业语音转化为文字怎么样_安徽听见科技
  8. 系统学习深度学习(三十八)--深度确定性策略梯度(DDPG)
  9. CDH使用Solr实现HBase二级索引
  10. 哈理工OJ 1926 函数式计算
  11. 利用Python处理逐日气象数据集(.txt文件)
  12. QT如何给exe添加图标
  13. LoopClosing中为什么要使用剥离尺度的sim3计算投影匹配
  14. emoji表情的处理和保存
  15. c语言-结构体实例笔记
  16. GS108E+GS105E+TP-LINK TL-WDR5620实现联通家庭宽带IPTV单线复用教程
  17. [CTFSHOW]命令执行55-74
  18. Qt 设置窗口背景图片的几种方法实例
  19. 分析Crash report
  20. 类脑计算将何去何从?

热门文章

  1. 十年技术进阶路:让我明白了三件要事。关于如何做好技术 Team Leader?如何提升管理业务技术水平?(10000字长文)...
  2. 轴承产生震动是什么原因?
  3. 盲目跟风,害的是你自己
  4. FlatBuffers vs Protocol Buffers
  5. Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
  6. inet_aton和inet_ntoa
  7. 简介一些黑盒测试的方法
  8. Android ViewFlipper 使用
  9. win10安装linux子系统详细教程(非虚拟机方式)
  10. Java学习路线,java学习教程(入门到精通)