单源最短路径-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. ...
随机推荐
- Linux内核同步机制之(三):memory barrier【转】
转自:http://www.wowotech.net/kernel_synchronization/memory-barrier.html 一.前言 我记得以前上学的时候大家经常说的一个词汇叫做所见即 ...
- Linux下音频编程-输出音频文件
程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...
- OTP【转】
转自:http://baike.baidu.com/link?url=58z3oZfEMvNRiDUmWrxtzfDhv--UZ1jaW4rBHg1d9kIWd6HQaYZ96DH8QAFopSZBK ...
- SQLServer2008 行转列3
with a as ( select 日期,学号,名字, '语文' as 科目,语文 as 分数 from tsco union all select 日期,学号,名字, '数学' as 科目,数学 ...
- leetcode:Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- Enable test automation in Testlink
Enabling Test Automation in Testlink Step 1: Change config settings in testlink config file Edit c ...
- 使用.9.png报错 Exception raised during rendering
Exception raised during rendering: Index: 2, Size: 2Exception details are logged in Window > Show ...
- git和其他版本控制系统的区别
所有除了Git以外的版本控制系统都使用增量存储方式来保存不同版本,而Git则在每一个commit时,保存一个整个文件的content copy,除非那个文件没有做过改动.Git和其他版本系统的主要区别 ...
- POJ 1847 Tram【Floyd】
题意:给出n个站点,每个站点都有铁路通向其他站点 如果当前要走得路恰好是该站点的开关指向的铁路,则不用扳开关,否则要手动扳动开关,给出起点和终点,问最少需要扳动多少次开关 输入的第一行是n,start ...
- linux 命令行字符终端terminal下强制清空回收站
回收站其实就是一个文件夹,存放被删掉的文件. ubuntu 回收站的路径: $HOME/.local/share/Trash/ 强制清空回收站: rm -fr $HOME/.local/share/T ...
