最短路之--spfa
2014-04-15 00:01
218 查看
其实 提到最短路 应该是先讲Dijkstra 但它的未进行优先队列优化的普通版本与昨天所讲的Prim实在太像了. 所以决定延后几天再讲吧.
今天晚上 去西厂听老蔡和XX 去讲他们的心理路程(找不到好的词语来修饰。。。。) 还是有很多感触的 差距还是很大的. 但往好了想 毕竟我也才大一 是吧? 还来得及。。。
打完这段话 突然想到了 自欺欺人 这4个字。。。
好了 切回正题。
今天 我们讲的spfa是bellman-ford的优化 关于这个算法最重要的事 应该是它是由我们西南交通大学的段丁凡 提出的.. 当时看到这个 还是很让人振奋的.
它是通过队列进行优化实现的 现在我们就具体来讲讲它的优化实现方式与过程吧
初始化的时候 将源点加入队列 每次从队列中取出一个元素 并将所有与它相邻的点进行松弛操作 若某个相邻的点松弛成功 则将其入队 直到队列中无任何元素为止 over .
可能 你会有疑惑 为什么 松弛成功的点 才能入队呢?
很简单 你可以这样想 如果松弛不成功 那么它与源点的相对距离没有缩减 那么假如有条路径 源点-该点-目标点 是没必要去尝试的 因为我并没有松弛成功 距离没有缩减
这边有必要提下 松弛操作 这个会在我们很多关于图论的算法中涉及到. 譬如上次提过的Prim就运用了它.
松弛--往简单了说 就是刷新该点与源点的最短距离 可能这个解释太过简单了 如果你想更详细的了解 自行百度吧。。
dist[i]表示源点到 I 的当前最短距离
linker[i]表示源点到I的当前最短路径中I点之前的一个点的编号
开始时 dist[i]全部初始化为+∞ 除离自身dist[S]=0 ;
linker[i]全部初始化为S
每次的迭代操作 取出队首V 依次枚举从V出发的边 V->U
判断 dist[v]+map[u][v] 与 dist[u] 的大小关系
若松弛成功 即离源点的相对距离缩短 并且若u不在队列中 就将u入队 放入队尾
这样 重复操作 持续迭代 直至队列为空 即所有点到S的最短路距离 就这样都确定了
特别要提一点 其实spfa并不是我们所讲述的那么好 它是效率不稳定的 一般情况下 我们用Dijkstra就可以解决 遇到任意2点间距离的话 可以用floyd算法 这些我们都会在
后面的随笔中涉及到
接下来 给出它的模板
View Code
这里 我并没有给它加以注释 因为我知道 如果你和我一样是初学者 当第一次看到这段代码的时候 即使看了我上面那段 又臭又长的叙述 肯定还是有很多疑惑的 我还是希望
你能去看更加详细的解释 加上 自己的思索 所以 我这边不想加以注释
spfa是我很喜欢的算法 感觉名字很cool。。。。
写完 恰好次日凌晨...
今天晚上 去西厂听老蔡和XX 去讲他们的心理路程(找不到好的词语来修饰。。。。) 还是有很多感触的 差距还是很大的. 但往好了想 毕竟我也才大一 是吧? 还来得及。。。
打完这段话 突然想到了 自欺欺人 这4个字。。。
好了 切回正题。
今天 我们讲的spfa是bellman-ford的优化 关于这个算法最重要的事 应该是它是由我们西南交通大学的段丁凡 提出的.. 当时看到这个 还是很让人振奋的.
它是通过队列进行优化实现的 现在我们就具体来讲讲它的优化实现方式与过程吧
初始化的时候 将源点加入队列 每次从队列中取出一个元素 并将所有与它相邻的点进行松弛操作 若某个相邻的点松弛成功 则将其入队 直到队列中无任何元素为止 over .
可能 你会有疑惑 为什么 松弛成功的点 才能入队呢?
很简单 你可以这样想 如果松弛不成功 那么它与源点的相对距离没有缩减 那么假如有条路径 源点-该点-目标点 是没必要去尝试的 因为我并没有松弛成功 距离没有缩减
这边有必要提下 松弛操作 这个会在我们很多关于图论的算法中涉及到. 譬如上次提过的Prim就运用了它.
松弛--往简单了说 就是刷新该点与源点的最短距离 可能这个解释太过简单了 如果你想更详细的了解 自行百度吧。。
dist[i]表示源点到 I 的当前最短距离
linker[i]表示源点到I的当前最短路径中I点之前的一个点的编号
开始时 dist[i]全部初始化为+∞ 除离自身dist[S]=0 ;
linker[i]全部初始化为S
每次的迭代操作 取出队首V 依次枚举从V出发的边 V->U
判断 dist[v]+map[u][v] 与 dist[u] 的大小关系
若松弛成功 即离源点的相对距离缩短 并且若u不在队列中 就将u入队 放入队尾
这样 重复操作 持续迭代 直至队列为空 即所有点到S的最短路距离 就这样都确定了
特别要提一点 其实spfa并不是我们所讲述的那么好 它是效率不稳定的 一般情况下 我们用Dijkstra就可以解决 遇到任意2点间距离的话 可以用floyd算法 这些我们都会在
后面的随笔中涉及到
接下来 给出它的模板
void spfa() { memset( vis, false , sizeof(vis) ); queue<int>qe; for(int i=0;i<n;i++) { dist[i]=inf; } dist[begin]=0; vis[begin]=true; qe.push(begin); while( !qe.empty() ) { int temp=qe.front(); qe.pop(); for(int i=0;i<n;i++) { if( dist[temp] + map[temp][i] < dist[i] ) { dist[i]= dist[temp]+map[temp][i]; if( !vis[i] ) { qe.push(i); vis[i]=true; } } } vis[temp]=false; } }
View Code
这里 我并没有给它加以注释 因为我知道 如果你和我一样是初学者 当第一次看到这段代码的时候 即使看了我上面那段 又臭又长的叙述 肯定还是有很多疑惑的 我还是希望
你能去看更加详细的解释 加上 自己的思索 所以 我这边不想加以注释
spfa是我很喜欢的算法 感觉名字很cool。。。。
写完 恰好次日凌晨...
相关文章推荐
- [模板]最短路 (Floyd, Spfa, Dijkstra,
- HDU-#2544 最短路(Dijkstra、Floyd、Bellman-Ford、SPFA)
- VIJOS-P1006 晴天小猪历险记之Hill spfa 最短路模型
- hdu 3832 Earth Hour(最短路 spfa dijkstra)
- 【HDU - 2066 一个人的旅行】 最短路 dijkstra,spfa
- hdu--2544--题如其名<最短路>--dij<priority_queue>||spfa<queue>
- bzoj1726 [Usaco2006 Nov]Roadblocks第二短路(spfa)
- 【POJ】3255 Roadblocks(次短路+spfa)
- 【NOIP2013】华容道 最短路优化搜索(spfa)
- HDU 1535 Invitation Cards(最短路 spfa)
- poj 2457 Part Acquisition 最短路spfa
- (CCF 201403-4)无线网络 最短路变形:节点访问限制 + [SPFA]
- 杭电3339————最短路(SPFA)+ 01背包
- 单源起点最短路SPFA——pku3013
- SPFA入门题-----hdu2544最短路
- 最短路SPFA——Big Christmas Tree ( POJ 3013 )
- HDU 3339 In Action(最短路(Spfa)+01背包)
- HDU 2544 最短路 SPFA
- 单源最短路_SPFA_C++
- POJ 2449 Remmarguts' Date 第K短路 A* + SPFA