1 Dijkstra算法

1.1 算法基本信息

  • 解决问题/提出背景

    • 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径)
  • 算法思想

    • 贪心算法

      • 按路径长度递增的次序,依次产生最短路径的算法
    • 【适用范围】Dijkstra算法仅适用于【权重为正】的图模型中
  • 时间复杂度

    • O(n^3)
  • 补充说明

    • 亦可应用于【多源最短路径】(推荐:Floyd算法(动态规划,O(n^3)))

      • Dijkstra 时间复杂度:O(n^3)

1.2 算法描述

  • 1.2.1 求解过程(具体思路)
  • 1.2.2 示例

1.2 编程复现

  • 1> 定义图模型(邻接矩阵表示法)的【基本存储结构体】
# define MaxInt 32767 // 表示极大值 即 ∞ (无穷大)
# define MVNum 100 // 最大顶点数 typedef int VertexType; // 假设顶点的数据类型为整型 typedef int ArcType; // 假设Vi与Vj之边的权值类型为整型 typedef struct {
VertexType vexs[MVNum]; // 顶点表 (存储顶点信息)
ArcType arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum,arcnum; // 图的当前顶点数与边数
}AMGraph; // Adjacent Matrix Graph 邻接矩阵图
  • 2> 定义 Dijkstra 算法的【辅助数据结构体】
bool S[MVNum]; // S[i] 记录从源点V0到终点Vi是否已被确定为最短路径长度  【划分确定与未确定: 跟贪心算法的适用范围(不可取消性)有直接联系】
// true:表已确定;false:表尚未确定
ArcType D[MVNum]; // D[i] 记录从源点V0到终点Vi的【当前】最短路径【长度】
int Path[MVNum]; // Path[i] 记录从源点V0到终点Vi的【当前】最短路径上【Vi的[直接前驱]的顶点序号】
  • 3> 初始化(邻接矩阵)带权有向图的图模型
void InitAMGraph(AMGraph &G){
cout<<"Please Input Vertexs Number:";
cin>>G.vexnum;
cout<<"\nPlease Directed Edges Number:";
cin>>G.arcnum; for(int i=0;i<MVNum;i++){
for(int j=0;j<MVNum;j++){
if(i!=j){ // 【易错】 初始化<Vi, Vj>时: <Vi,Vj> 路径长度无穷大 (i!=j)
G.arcs[i][j] = MaxInt;
} else { // 【易错】 初始化<Vi, Vj>时: <Vi,Vi>【自回环】路径长度为0 (i==i)
G.arcs[i][j] = 0;
}
}
}
for(int i=0;i<G.vexnum;i++){
G.vexs[i] = i;
}
cout<<"\nPlease Input All Directed Edges and their Weight now:";
cout<<"\nDirected Edges(i,j,weight): "<<endl;
int i,j;
int weight;
for(int k=0;k<G.arcnum;k++){
// cout<<"("<<(k+1)<<") ";
cin>>i;cin>>j;cin>>weight;
G.arcs[i][j] = weight;
}
cout<<endl;
}
  • 4> Dijkstra算法:求解单源最短路径
void ShortestPath_Dijkstra(AMGraph G, int V0){
//step1 n个顶点依次初始化
int n =G.vexnum;
for(int v=0;v<n;v++){
S[v] = false;
D[v] = G.arcs[V0][v];
if(D[v]<MaxInt){
Path[v] = V0;
} else {
Path[v] = -1;
}
}
//step2 将源点V0划入已确定集合S中
S[V0] = true;
D[V0] = 0; // 源点V0到源点V0的最短路径长度必然为0
//step3 贪心算法策略:
// 3.1 循环遍历所有结点:
// 3.2 先确定当前最短路径的终点v;
// 3.3 然后,将v划入已确定集合S中;
// 3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径
int v;
int min;
D[G.vexnum] = MaxInt;
for(int i=1;i<n;i++){//3.1循环遍历所有结点 (即 求从源点V0到图中每一顶点(共计n-1个顶点)的最短路径)
//3.2 确定当前最短路径的终点v;
min = MaxInt;
for(int w=0;w<n;w++){
if(S[w]==false && D[w]<min){//比本轮循环中,已知的最短路径还短 【易错/易漏】 S[w]==false : 必须满足当前结点 Vw 属于尚未确定的结点
v = w;
min = D[w];
}
}
//3.3 然后,将v划入已确定集合S中;
S[v] = true;
//3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径
for(int w=0;w<n;w++){
//↓更新Vw结点的最短路径长度为 D[v] + G.arcs[v][w]
//cout<<"S["<<w<<"]:"<<S[w]<<"D["<<v<<"]"<<D[v]<<"G.arcs["<<v<<"]["<<w<<"]"<<"D["<<w<<"]"<<D[w]<<endl;
if(S[w]==false && (D[v] + G.arcs[v][w] < D[w])){//【易错/易漏】 S[w]==false : 必须满足当前结点 Vw 属于尚未确定的结点
D[w] = D[v] + G.arcs[v][w];
Path[w] = v; // 更新 结点Vw的前驱为 v
}
}
v = G.vexnum;
}
}
  • 5> 输出结果 D[i]、Path[j]
void OutputD(AMGraph G, int V0){
cout<<"Shortest Distance Weight of the Pair of Directed Vertices("<<V0<<", j):"<<endl;
for(int j=0;j<G.vexnum;j++){
cout<<D[j]<<"\t";
}
cout<<endl;
} void OutputPath(AMGraph G,int V0){
cout<<"Shortest Distance Path("<<V0<<",j) of the Pair of Directed Vertices:"<<endl;
for(int j=0;j<G.vexnum;j++){
cout<<Path[j]<<"\t";
}
cout<<endl;
}
  • 6> 执行:Main函数
int main(){
int V0; //源点V0的下标
AMGraph G;
InitAMGraph(G); cout<<"Please Input the Index of Source Node 'V0':";
cin>>V0;
ShortestPath_Dijkstra(G, V0);
OutputD(G, V0);
OutputPath(G, V0);
return 0;
}
  • 7> Test: Output of Main
Please Input Vertexs Number:6

Please Directed Edges Number:8

Please Input All Directed Edges and their Weight now:
Directed Edges(i,j,weight):
1 2 5
0 2 10
3 5 10
4 3 20
0 4 30
2 3 50
4 5 60
0 5 100 Please Input the Index of Source Node 'V0':0 Shortest Distance Weight of the Pair of Directed Vertices(0, j):
0 32767 10 50 30 60 Shortest Distance Path(0,j) of the Pair of Directed Vertices:
0 -1 0 4 0 3

2 参考文献

  • 《数据结构(C语言版/ 严蔚敏 李冬梅 吴伟民 编)》

[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)的更多相关文章

  1. 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)

    文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...

  2. 单源最短路径-迪杰斯特拉算法(Dijkstra's algorithm)

    Dijkstra's algorithm 迪杰斯特拉算法是目前已知的解决单源最短路径问题的最快算法. 单源(single source)最短路径,就是从一个源点出发,考察它到任意顶点所经过的边的权重之 ...

  3. 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析

    什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...

  4. 最短路径-迪杰斯特拉(dijkstra)算法及优化详解

    简介: dijkstra算法解决图论中源点到任意一点的最短路径. 算法思想: 算法特点: dijkstra算法解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算 ...

  5. 最短路径 - 迪杰斯特拉(Dijkstra)算法

    对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...

  6. JS实现最短路径之迪杰斯特拉(Dijkstra)算法

    最短路径: 对于网图来说,最短路径是指两个顶点之间经过的边上权值和最少的路径,我们称第一个顶点是源点,最后一个顶点是终点 迪杰斯特拉 ( Dijkstra) 算法是并不是一下子就求出 了 Vo 到V8 ...

  7. 最短路径算法-迪杰斯特拉(Dijkstra)算法在c#中的实现和生产应用

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止 贪心算法(Greedy ...

  8. 迪杰斯特拉Dijkstra算法介绍

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  9. [从今天开始修炼数据结构]图的最短路径 —— 迪杰斯特拉算法和弗洛伊德算法的详解与Java实现

    在网图和非网图中,最短路径的含义不同.非网图中边上没有权值,所谓的最短路径,其实就是两顶点之间经过的边数最少的路径:而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,我们称路径上第 ...

  10. 数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++

    数据结构图之三(最短路径--迪杰斯特拉算法)   [1]最短路径 最短路径?别乱想哈,其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两 ...

随机推荐

  1. SQL性能优化思路

    1. 尽可能把数据的存储和计算放入Memory而不是Disk,且减少IO操作,比如运用Redis等缓存技术 2. 对数据表进行精心设计,特别是大数据表,对常用数据字段进行适当的冗余,尽可能避免分表导致 ...

  2. 【jmeter】无GUI界面,命令行运行测试脚本

    一.应用场景 1.无需交互界面或受环境限制(linux text model) 2.远程或分布式执行 3.持续集成,通过shell脚本或批处理命令均可执行,生成的测试结果可被报表生成模块直接使用,便于 ...

  3. JAVA遇见HTML——JSP篇:JSP内置对象(下)

    什么是session session表示客户端与服务器的一次会话 Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间 从上述 ...

  4. Vuex的mapGetters方法使用报错

    报错信息: ERROR in ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script ...

  5. AutoMapper 的简单使用

    var config = new MapperConfiguration( cfg => cfg.CreateMap<SYS_Menu, MenuTreeNode>() .ForMe ...

  6. Lua 学习之基础篇四<Lua table(表)>

    table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组.字典等. Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil. Lua ta ...

  7. Java集合--Collection

    概要 首先,我们对Collection进行说明.下面先看看Collection的一些框架类的关系图: Collection是一个接口,它主要的两个分支是:List 和 Set. List和Set都是接 ...

  8. mysql:用户自定义变量关联失效

    自定义变量的属性和限制 使用自定义变量的查询,无法使用查询缓存. 不能在使用常量或者标识列的地方使用自定义变量,例如表名.列明和LIMIT子句中. 用户自定义变量的生命周期是在一个连接中有效,所以不能 ...

  9. Codeforces Round #585 (Div. 2) A. Yellow Cards(数学)

    链接: https://codeforces.com/contest/1215/problem/A 题意: The final match of the Berland Football Cup ha ...

  10. Educational Codeforces Round 72 (Rated for Div. 2) C题

    C. The Number Of Good Substrings Problem Description: You are given a binary string s (recall that a ...