算法基础 - 单源点最短路径SPFA
来源:互联网 发布:软件测试经典案例 编辑:程序博客网 时间:2024/06/06 09:06
SPFA是非常简单的最短路径算法,思想就是从起点开始,进行宽度优先搜索,不断松弛S点到其他相邻点的距离。如果松弛了点B,则把点B放到队列里。假如点B已经在队列里了,就不要放了,判断在不在队列可以用个数组来表示。
引用一段hihocoder上的解释:
构造一个队列,最开始队列里只有(S, 0)——表示当前处于点S,从点S到达该点的距离为0,然后每次从队首取出一个节点(i, L)——表示当前处于点i,从点S到达该点的距离为L,接下来遍历所有从这个节点出发的边(i, j, l)——表示i和j之间有一条长度为l的边,将(j, L+l)加入到队尾,最后看所有遍历的(T, X)节点中X的最小值就是答案咯~”小Ho对于搜索已经是熟稔于心,张口便道。
SPFA算法呢,其实某种意义上就是宽度优先搜索的优化——如果你在尝试将(p, q)
加入到队尾的时候,发现队列中已经存在一个(p, q')
了,那么你就可以比较q和q’:如果q>=q'
,那么(p, q)
这个节点实际上是没有继续搜索下去的必要的——算是一种最优化剪枝吧。而如果q < q'
,那么(p, q')
也是没有必要继续搜索下去的——但是它已经存在于队列里了怎么办呢?很简单,将队列中的(p, q')
改成(p, q)
就可以了!”“那我该怎么知道队列中是不是存在一个
(p, q')
呢?”
维护一个position[1..N]
的数组就可以了,如果不在队列里就是-1,否则就是所在的位置!”“所以说这本质上就是宽度优先搜索的剪枝咯?”小Ho问道。
小Hi笑道:“怎么可能!SPFA算法其实是BELLMAN-FORD算法的一种优化版本,只不过在成型之后可以被理解成为宽度优先搜索的!这个问题,我们会在之后好好讲一讲的!
代码如下:
#include <iostream>#include <cstring>#include <string>#include <queue>using namespace std;struct Node{ int val; int len; Node * next; Node():val(-1),len(-1), next(NULL){} Node(int x, int le): val(x), len(le), next(NULL){}};long long SPFA(Node node[], int M, int S, int T){ queue<int> st; st.push(S); int flag[M+5]; long long dist[M+5]; for(int i = 0; i < M+5; i++){ flag[i] = 0; dist[i] = -1; } dist[S] = 0; flag[S] = 1; while(!st.empty()){ int cur = st.front(); st.pop(); flag[cur] = 0; Node * temp = node[cur].next; while(temp != NULL){ if(dist[temp->val] == -1 || dist[temp->val] > (dist[cur]+temp->len)){ dist[temp->val] = dist[cur]+temp->len; if(flag[temp->val] == 0){ st.push(temp->val); flag[temp->val] = 1; } } temp = temp->next; } } return dist[T];}int main(){ int M,N,S,T; // M 顶点个数, N 边个数, S起点, T 终点 while(cin>>M>>N>>S>>T){ Node node[M+5]; int st, en, le; for(int i = 0; i < N;i++){ cin>>st>>en>>le; //st边起点 en边终点 le边长度 Node * temp = new Node(en,le); temp->next = node[st].next; node[st].next = temp; /*如果是无向图加上这三条语句 temp = new Node(st,le); temp->next = node[en].next; node[en].next = temp; */ } cout<<SPFA(node, M, S, T)<<endl; }}
大致如上
- 算法基础 - 单源点最短路径SPFA
- 单源点最短路径----Dijkstra算法
- 单源点最短路径(dijkstra算法)
- NYOJ115城市平乱_单源点最短路径(spfa)
- SPFA算法 快速Bellaman-ford算法 源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 【数据结构】算法7.15 Dijkstra算法 单源点最短路径
- 单源点最短路径Dijkstra算法的JAVA实现
- 单源点最短路径算法的设计与实现
- 单源点最短路径Dijkstra算法的JAVA实现
- 单源点最短路径算法(dijkstra)
- 单源点最短路径 c++实现 分支限界算法
- windows下OpenCV在VS2010中的配置
- redis高可用方案Sentinel配置
- throw thorws 区别
- final,finally和finalize的区别
- 用ndk-gdb调试Native
- 算法基础 - 单源点最短路径SPFA
- 图解红黑树之插入与删除
- OBJ-C ARC概念及原理+分类 学习笔记
- 魔兽世界私服Trinity,从源码开始
- 扣丁音乐(四)——本地音乐加载
- OBJ-C block + protocol 学习笔记
- CC2538内存分配问题
- 软件开发——软技能(背景)
- OBJ-C NSString + NSRange + NSMutableString 学习笔记