单源最短路径-Dijkstra算法
1.算法标签
贪心
2.算法描述
具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的。
对于Dijkstra算法,最重要的是维护以下几个数据结构:
- 顶点集合S : 表示已经找出从源点出发最短路径的顶点集合
- 顶点集合Q: S在所有顶点集合中的补集,即V-S
- 距离数组dist : 在程序执行过程中,如果序号为n的顶点已经在S中,那么dist[n]表示从源点start到顶点n的最短距离,否则dist[n]的值将在程序执行过程中不断收敛。
- 路径数组previous: 当程序执行完成之后,previous[n]表示最短路径中顶点n的前一个顶点
程序执行时,每轮循环中,对Q中每个顶点u,计算源点经由S中顶点直接到达u的路径长度最小值,存入dist数组中,每轮循环只往S中加入一个顶点,这个顶点是Q中顶点dist值最小的那个,因此这是个贪心策略,为什么贪心策略是正确的?
- Dijskstra默认每条边都是正权值
- 因为S中的顶点的最短路径已经找到,所以加入的这个点肯定找不到一条更短的到源点的路径,否则说明S中的路径不是最短路径。
3.实现说明
实现时,Dijkstra算法可能会有多种改进,比如图用邻接表的形式存储,可以在稀疏图中获得更快的时间,然后计算dist最小值可以用最小堆来实现,这样就不必每次线性查找
4.一个例子(图片来源)
5.代码实现
//aouthor:areslipan
vector<int> Dijkstra(vector<vector<int> > &g, int vNum,int start)
{
vector<int>path(vNum,-1);//-1表示路径未找到
vector<int>dist(vNum,MYINF);
dist[start]=0;
set<int>source;//一旦一个点距离源点start最短路径被找到,那么该点就被加入集合source中
set<int>dest; //source 的补集
for(int i=0;i<vNum;++i)dest.insert(i); set<int>::iterator iter_s;
set<int>::iterator iter_d; int cur=start; while(!dest.empty())
{
int curMin=MYINF; //选出dest中dist最小的那个归入source中
for(iter_d=dest.begin();iter_d!=dest.end();++iter_d)
{
if(curMin>dist[*iter_d])
{
curMin=dist[*iter_d];cur=*iter_d;
}
} source.insert(cur);
dest.erase(cur); //加入一个新顶点之后开始更新dest中顶点的dist值,此处可以用最小堆优化
for(iter_s=source.begin();iter_s!=source.end();++iter_s)
{
for(iter_d=dest.begin();iter_d!=dest.end();++iter_d)
{
if((g[*iter_s][*iter_d]+dist[*iter_s])<dist[*iter_d])
{
dist[*iter_d]=g[*iter_s][*iter_d]+dist[*iter_s];
path[*iter_d]=*iter_s;
}
}
}
} return path;
}
上面这个程序算法时间复杂度较高,在优化实现的时候算法复杂度可以降低到O(NlgN),分析见wiki,这个程序只是作为说明的用途。
6.完整的程序文件
7.参考
参考1:http://www.wutianqi.com/?p=1890
参考2: wiki
参考3:文中链接
单源最短路径-Dijkstra算法的更多相关文章
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 单源最短路径——dijkstra算法
dijkstra算法与prim算法的区别 1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...
- 单源最短路径 dijkstra算法实现
本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图.而且连通,有向图,不连通图的做法相似. 算法简述: 首先确定"单源"的源.假设是第0个顶点. 维护三个数组 ...
- 单源最短路径——Dijkstra算法学习
每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...
- [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...
- matlab练习程序(单源最短路径Dijkstra)
图的相关算法也算是自己的一个软肋了,当年没选修图论也是一大遗憾. 图像处理中,也有使用图论算法作为基础的相关算法,比如图割,这个算法就需要求最大流.最小割.所以熟悉一下图论算法对于图像处理还是很有帮助 ...
- 单源最短路径---Bellman-Ford算法
传送门: Dijkstra Bellman-Ford SPFA Floyd 1.Dijkstra算法的局限性 像上图,如果用dijkstra算法的话就会出错,因为如果从1开始,第一步dist[2] = ...
- 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
- 单源最短路径Dijkstra和优先级算法
百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...
随机推荐
- CF 2013-2014CTS01E04(Killer Challenge-将质因数存在 进行Bitmask)
首先,把P进行质因数分解,每一个不用的质因数压成1位 f[i][j]表示1前i位用j“拥有”的质因数表示. 然后都懂得... #include<cstdio> #include<cs ...
- centos6.5 中文
之前在网上查了不少资料,很多网友在网上都说,在shell命令下输入: # vi /etc/sysconfig/i18n 然后修改LANG="en_US.UTF-8" ...
- Longest Valid Parentheses(最长有效括号)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- D3D中深度测试和Alpha混合的关系
我在学习D3D的深度测试和Alpha混合的时候,有一些遗憾.书上提供的例子里说一定要先渲染不透明物体,再渲染透明物体,对渲染状态的设置也有特殊要求.我看的很晕.自己查图形学的书,上网找资料,结果还是糊 ...
- Android实现分享内容到微信朋友圈
原文地址:http://yanwushu.sinaapp.com/android_wechat_share/ 由于需求,要实现在应用中实现分享文字+图片到微信朋友圈.在网上找了一些资料,总结如下: 思 ...
- java.io.InvalidClassException: com.master.CurrentMessages; local class incompatible:
报错信息如下: java.io.InvalidClassException: com.master.CurrentMessages; local class incompatible: stream ...
- web.xml中webAppRootKey
------------------------------------------------------------------------------------------------1. w ...
- request.getRequestDispatcher()和response.sendRedirect()
request.getRequestDispatcher("/homeMainAction_mainUI.do").forward(getRequest(), getRespons ...
- HDU 2516 (Fabonacci Nim) 取石子游戏
这道题的结论就是,石子的个数为斐波那契数列某一项的时候,先手必败:否则,先手必胜. 结论很简单,但是证明却不是特别容易.找了好几篇博客,发现不一样的也就两篇,但是这两篇给的证明感觉证得不清不楚的,没看 ...
- HDU 2062 Subset sequence
我是把它当做一道数学题来做的. 这篇题解写的有点啰嗦,但是是我最原始的思维过程. 对于一个集合An= { 1, 2, …, n },在n比较小的情况下,在纸上按字典顺序把所有子集排列一下. 以n=3, ...
