最短路径问题是一个很常见的问题,与其相关的算法也很多,本文总结了三种不同的算法来解决这个问题,并进行了一些对比分析。本文不像教科书那样详细介绍每种算法的具体细节,可以阅读这篇文章:http://dsqiu.iteye.com/blog/1689163,里面讲的和详细。
一.Dijkstra算法
相信说到单源最短路径问题,大家都会想到著名的Dijkstra算法。Dijkstra算法本质上是一种贪心算法,可以把所有节点分为两个集合S(已找到最短路径的集合)和T(剩余节点的集合),每步都从T中选择一个权值最小的节点加入到S中,同时对与该节点相连的并且在T中的节点进行松弛操作。正因为这种贪心的思想,导致了Dijkstra算法不适用于带有负权值的环的图,但适用于带有权值为负的边的图。
此处稍微解释一下,我们知道贪心算法的思想是每步选择最优,从而使得最终得到最优结果。但当图中存在权值为负的环时,局部最优不一定会导致最终最优。例如在下图中:
源节点为0,按照Dijkstra算法的规则,第一步选择节点1加入集合S,则节点0到节点1的最短路径权值为4,但如图可知最短路径为0-2-1,权值为3。故Dijkstra算法不适用于带有负权值的环的图。
代码:
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;
struct State
{
int index, weight;
State(int i, int w) :index(i), weight(w){}
bool operator<(const State& S) const
{
return weight > S.weight;
}
};
int main()
{
ifstream in("data.txt