单源最短路径-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. ...
随机推荐
- 第九篇 ERP实施项目中需求分析及方案设计的通用思路
顾问实施ERP就好想医生给患者看病抓药,不但具有类似的过程,而且具有其通用的思路. --详见http://bbs.erp100.com/thread-272856-1-1.html 顾问实施ERP就好 ...
- 【Todo】InnoDB、MyISAM、数据库引擎
关于InnoDB和MyISAM引擎的对比,下面这篇讲的挺好 http://www.cnblogs.com/vicenteforever/articles/1613119.html 这一篇关于InnoD ...
- hdu2847(暴力)
去年看的一道题目,但是竟然傻傻的用dfs+循环链表去做. 简直傻到爆. 不过现在做这题还是想了好久而且还有好几次WA,其实这题还是很水的.直接暴力枚举就行了,枚举的前提是要算好复杂度, 可以知道的是 ...
- 【笨嘴拙舌WINDOWS】窗体样式
"眼睛是人类心灵的窗口,打开窗口,你就能看到整个世界" 在PC时代,计算机的显示屏就是真个世界,WINDOWS将真个世界分解为一个个的窗口,每个窗口有自己的容貌,下面我们将一一揭开 ...
- 51nod1431 快乐排队
神???.我们可以发现无论怎么交换ai+i都是不变的.那么这样就可以了 #include<cstdio> #include<cstring> #include<cctyp ...
- LeetCode Binary Tree Maximum Path Sum 二叉树最大路径和(DFS)
题意:给一棵二叉树,要求找出任意两个节点(也可以只是一个点)的最大路径和,至少1个节点,返回路径和.(点权有负的.) 思路:DFS解决,返回值是,经过从某后代节点上来到当前节点且路径和最大的值.要注意 ...
- 8个必备的PHP功能开发 (转)
做过PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PHP功能,个个都非常实用,希望各位PHP开发者能够掌握. 1.传 ...
- Linux技巧:一次删除一百万个文件最快方法
昨天,我看到一个非常有趣的删除一个目录下的海量文件的方法.这个方法来自http://www.quora.com/How-can-someone-rapidly-delete-400-000-files ...
- 对于fmri的设计矩阵构造的一个很直观的解释-by 西南大学xulei教授
本程序意在解释这样几个问题:完整版代码在本文的最后. 1.实验的设计如何转换成设计矩阵? 2.设计矩阵的每列表示一个刺激条件,如何确定它们? 3.如何根据设计矩阵和每个体素的信号求得该体素对刺激的敏感 ...
- 【英语】Bingo口语笔记(74) - put系列
