Dijkstra最短路径算法[贪心]
Dijkstra算法的标记和结构与prim算法的用法十分相似。它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树。但千万不要把它们混淆了。它们解决的是不同的问题,因此,所操作的优先级也是以不同的方式计算的:Dijkstra算法比较路径的长度,因此必须把边的权重相加,而prim算法则直接比较给定的权重。
源最短路径问题
给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。
前面Bellman-Ford最短路径算法讲了单源最短路径的Bellman-Ford算法(动态规划算法)。这里介绍另外一个更常见的算法Dijkstra算法。
Dijkstra算法和 最小生成树Prim算法最小生成树算法非常类似,大家可以先熟悉下个算法。两个算法都是基于贪心算法。虽然Dijkstra算法相对来说比Bellman-Ford 算法更快,但是不适用于有负权值边的图,贪心算法决定了它的目光短浅。而Bellman-Ford 算法从全局考虑,可以检测到有负权值的回路。
这里模仿MST(Minimum Spanning Tree)的Prim算法,我们创建一个SPT(最短路径树),最初只包含源点。我们维护两个集合,一组已经包含在SPT(最短路径树)中的顶点S集合,另一组是未包含在SPT内的顶点T集合。每次从T集合中选择到S集合路径最短的那个点,并加入到集合S中,并把这个点从集合T删除。直到T集合为空为止。
举例说明,如下图所示的图:
S集合最初为空,然后选取源点0,S集合为 {0},源点到其它所有点的距离为 {0, 4, INF, INF, INF, INF, 8, INF} 。图中蓝色表示 SPT,迭代的过程如下
最终得到 SPT(最短路径树) 如下:
算法C++实现:
我们使用Boolean 数组sptSet[] (也有习惯用visit[]命名,表示是否访问过),来表示顶点是否为有SPT中。sptSet[v]=true,说明顶点v在SPT中。 dist[] 用来存储源点到其它所有点的最短路径。
#include<iostream>
#include<stdio.h>
#include<limits.h>
using namespace std; const int V=;
//从未包含在SPT的集合T中,选取一个到S集合的最短距离的顶点
int getMinIndex(int dist[V],bool sptSet[V])
{
int min=INT_MAX,min_index;
for(int v=;v<V;v++)
{
if(!sptSet[v]&&dist[v]<min)
min=dist[v],min_index=v;
}
return min_index;
} //打印结果 void printSolution(int dist[],int n)
{
printf("Vertex Distance from Source\n");
for(int i=;i<V;i++)
printf("%d\t\t %d\n",i,dist[i]);
} //source 代表顶点
void dijkstra(int graph[V][V],int source)
{
int dist[V];// 存储结果,从源点到 i的距离
bool sptSet[V]; // sptSet[i]=true 如果顶点i包含在SPT中 // 初始化. 0代表不可达
for(int i=;i<V;i++)
{
dist[i]=(graph[source][i]==)?INT_MAX:graph[source][i];
sptSet[i]=false;
}
// 源点,距离总是为0. 并加入SPT
dist[source]=;
sptSet[source]=true; // 迭代V-1次,因此不用计算源点了,还剩下V-1个需要计算的顶点。
for(int count=;count<V-;count++)
{
// u,是T集合中,到S集合距离最小的点,u开始在T集合中,然后加入到S集合
int u=getMinIndex(dist,sptSet);
// 加入SPT中
sptSet[u]=true;
for(int v=;v<V;v++)
{
//满足以下4个条件
//1. 点v还没有加入到spt中
//2. 点u和v之间可达
//3. 点u是可达的,距离不是无穷
//4. 经过点u之后的距离小于直接到达点v的距离
if(!sptSet[v]&&graph[u][v]&&dist[u]!=INT_MAX&&dist[u]+graph[u][v]<dist[v])
dist[v]=dist[u]+graph[u][v];
}
}
printSolution(dist,V);
} int main()
{
int graph[V][V]={ { , , , , , , , , },
{ , , , , , , , , },
{, , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , }
}; dijkstra(graph, ); return ;
}
运行结果如下:输出源点0到其它各个顶点的最短距离:
Dijkstra最短路径算法[贪心]的更多相关文章
- 数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!
前言 去年在数据结构(c++)的Dijkstra教学算法案例中,发现了一个 bug 导致算法不能正常的运行,出错代码只是4行的for循环迭代代码. 看到那里就觉得有问题,但书中只给了关键代码的部分,其 ...
- Java邻接表表示加权有向图,附dijkstra最短路径算法
从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...
- 练习 Dijkstra 最短路径算法。
练习 Dijkstra 最短路径算法. #coding: utf-8 # Author: woodfox, Oct 14, 2014 # http://en.wikipedia.org/wiki/Di ...
- 一篇文章讲透Dijkstra最短路径算法
Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...
- Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法
1. 前言 因无向.无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找. 但是,无论是有向.还是无向,只要是加权图,最短路径长度的定义是:起点到终点之间所 ...
- Dijkstra 最短路径算法 秒懂详解
想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstr ...
- Dijkstra最短路径算法实例
#include <stdio.h>#include <stdlib.h>/* Dijkstra算法 */#define VNUM 5#define MV 65536int P ...
- 关于Dijkstra最短路径算法
Dijkstra算法,不是很明白,今天找了一些博客看了一下,决定自己也写一个为以后忘记的时候可以看做准备. 实际上,如果理解没错的话,该算法实际上和枚举法有点像,只不过,在选取出发路径的路径都是最短路 ...
- SRM 583 Div II Level Three:GameOnABoard,Dijkstra最短路径算法
题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12556 用Dijkstra实现,之前用Floyd算法写了一个, ...
随机推荐
- HDU5758 Explorer Bo 树形dp
我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 ...
- CABasicAnimation
几个可以用来实现热门APP应用PATH中menu效果的几个方法 +(CABasicAnimation *)opacityForever_Animation:(float)time //永久闪烁的动画 ...
- 在PC上测试移动端网站和模拟手机浏览器的5大方法
在PC上测试移动端网站和模拟手机浏览器的5大方法 来源:互联网 作者:佚名 时间:03-19 10:14:54 [大 中 小] 最近公司要开发网站的移动版,让我准备准备知 ...
- 如何用Entity Framework 6 连接Sqlite数据库[转]
获取Sqlite 1.可以用NuGet程序包来获取,它也会自动下载EF6 2.在Sqlite官网上下载对应的版本:http://system.data.sqlite.org/index.html/do ...
- 多校7 HDU5818 Joint Stacks
多校7 HDU5818 Joint Stacks 题意:n次操作.模拟栈的操作,合并的以后,每个栈里的元素以入栈顺序排列 思路:开三个栈,并且用到了merge函数 O(n)的复杂度 #include ...
- .net,mvc使用bootstrap做一个标准后台
今天准备搭一个公用后台,使用bootstrap,方便今后开发,顺便mark一下 后期列表页将使用kendo-ui,增强后台的效果 下面是代码... login页面 @{ Layout = null; ...
- C# 与 VC Dll 传输信息
考虑: 使用string类型传送: 在VC Dll中解析字符: 使用 string 类型将解析的类型传送到C#程序中: 建立VC解析的函数,提高代码可重用性
- 《APUE》中的函数整理
第1章 unix基础知识 1. char *strerror(int errnum) 该函数将errnum(就是errno值)映射为一个出错信息字符串,返回该字符串指针.声明在string.h文件中. ...
- Could not bind factory to JNDI
将hibernate.cfg.xml中 <session-factory name="SessionFactory">的name属性去掉即可
- html5 标签
按字母顺序排列的标签列表 4: 指示在 HTML 4.01 中定义了该元素 5: 指示在 HTML 5 中定义了该元素 标签 描述 4 5 <!--...--> 定义注释. 4 5 < ...