SPFA算法 - Bellman-ford算法的进一步优化
2017-07-27 22:18:11
writer:pprp
SPFA算法实质与Bellman-Ford算法的实质一样,每次都要去更新最短路径的估计值。
优化:只有那些在前一遍松弛中改变了距离点的值的点,才可能引起他们邻接点的距离估计值的改变;
做法:使用队列来缩小搜索范围的;
首先要将个点距离估计值设为+无穷,并将起始点加入队列。如果通过队列中的点i到相邻点j的距离小于原来到点j的距离,
即d[j]>d[i]+w[i][j]则d[j] = d[i] + w[i][j];将j点加入队列。当队列为空的时候,才能说明一丘处从起始点到任一点的最短距离。
为了防止同一个点多次出现在队列里,需要对该点做标记以确定带点是够存在于队列中;
注意点:仅当图不存在负权回路,SPFA才能正常工作;
判断负权回路方法有很多:
- 记录每个节点的进队次数,超过n说明有负权;
- 记录这个节点在路径所处位置ord[i],每次更新的时候ord[i] = dor[x]+1;超过n证明有负权
代码如下:
#include <iostream>
#include <queue> using namespace std; const int INF = ; struct node
{
int n;
int v;
node*next;
node()
{
n = ;
next = NULL;
}
}*e[]; //存放每一个点到别的点的边
int d[]; //估计值
bool c[]; //判断该顶点是否存在与队列中
queue<int> qu; //队列
int n,m; //n是顶点数,m是边的数目 void init()
{
cin >> n >> m;
node*p;
int x,y,v;
for(int i = ; i <= n; i++)
{
cin >> x >> y >> v;
p = new node();
p->n = y;
p->v = v;
if(e[x]==NULL)
e[x] = p;
else
{
p->next = e[x]->next;
e[x]->next = p;
}
}
} void spfa(int x)
{
int i;
node*p;
qu.push(x); // 将起始点加入队列
for(i = ; i <= n; i++)
d[i] = INF;
d[x] = ;
for(i =; i<=(int)qu.size(); i++) //读取队列
{
p = e[qu.front()]; //和qu相连的边
while(p!=NULL)
{
if(d[qu.front()]+p->v < d[p->n])
{
d[p->n] = d[qu.front()]+p->v; //更新距离
if(!c[p->n]) //如果p->n点没有在队列里
{
c[p->n] = ;
qu.push(p->n);
}
}
p = p->next; //下一个点
}
c[qu.front()]=;
qu.pop(); //该点出队
}
for(i=; i<=n; i++)
cout <<d[i]<<" ";
cout << endl; } int main()
{
init();
spfa();
return ;
}
之后还要再看一下
SPFA算法 - Bellman-ford算法的进一步优化的更多相关文章
- Bellman—Ford算法思想
---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】
题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...
- poj1860 bellman—ford队列优化 Currency Exchange
Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22123 Accepted: 799 ...
- 图论——最短路径 Dijkstra算法、Floyd算法
1.弗洛伊德算法(Floyd) 弗洛伊算法核心就是三重循环,M [ j ] [ k ] 表示从 j 到 k 的路径,而 i 表示当前 j 到 k 可以借助的点:红色部分表示,如果 j 到 i ,i 到 ...
- uva 558 - Wormholes(Bellman Ford判断负环)
题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...
- 图论算法——最短路径Dijkstra,Floyd,Bellman Ford
算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...
- 机器学习优化算法之EM算法
EM算法简介 EM算法其实是一类算法的总称.EM算法分为E-Step和M-Step两步.EM算法的应用范围很广,基本机器学习需要迭代优化参数的模型在优化时都可以使用EM算法. EM算法的思想和过程 E ...
- 算法 | 串匹配算法之KMP算法及其优化
主串 s:A B D A B C A B C 子串 t: A B C A B 问题:在主串 s 中是否存在一段 t 的子串呢? 形如上述问题,就是串匹配类问题.[串匹配--百度百科] 串匹配问题是一 ...
- 行为识别笔记:improved dense trajectories算法(iDT算法)(转载)
iDT算法是行为识别领域中非常经典的一种算法,在深度学习应用于该领域前也是效果最好的算法.由INRIA的IEAR实验室于2013年发表于ICCV.目前基于深度学习的行为识别算法效果已经超过了iDT算法 ...
随机推荐
- grunt 相关知识
/** * Created by lee on 2014.07.02 002. */ module.exports = function (grunt) { // 项目配置 grunt.initCon ...
- PHP数组遍历详解
一.PHP数组简介 1.PHP数组的分类 按照下标的不同分为关联数组和索引数组①索引数组:下标从0开始依次增长②关联数组:下标为字符串格式,每个下标字符串与数组的值一一对应,(有点像对象的键值对) 下 ...
- scrapy 原理,结构,基本命令,item,spider,selector简述
原理,结构,基本命令,item,spider,selector简述 原理 (1)结构 (2)运行流程 实操 (1) scrapy命令: 注意先把python安装目录的scripts文件夹添加到环境变量 ...
- Android 屏幕切换动画
public void overridePendingTransition (int enterAnim, int exitAnim) Call immediately after one of th ...
- android studio上传项目到github报错Successfully created project 'Demo' on GitHub, but initial commit failed:
今天博主正在愉快地学习在AndroidStudio中使用Git,结果报了下面这个错∑(っ°Д°;)っ: Can't finish GitHub sharing process Successfully ...
- Android View体系 系列文章
http://www.cnblogs.com/Free-Thinker/p/6768783.html
- AVL(二叉平衡树) 的实现
一颗AVL树是其每个节点的左子树与右子树的高度最多差1的二叉查找树. 在插入过程中,利用旋转的办法保持这个性质. 共分四种情形: 1. 树T的左孩子的左子树上新插入节点导致破坏平衡性: 如下图左边所 ...
- python的变量类型(Day6)
Python的变量类型 变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符. 变量赋值 Python 中的变量赋值不需要类型声明 等号(=)用来给变量赋值,等号左边为变量值,等号右边是存储在 ...
- 微信小程序组件button
表单组件button:官方文档 Demo Code: var types=['default', 'primary', 'warn']; var pageObject = { data: { defa ...
- TCP/IP 网络结构