首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v0到每个终点vi的最短路径的长度。

它的初态为:若从v0到vi有弧,则D[i]为弧上的权值;否则,置D[i]为∞。

显然,长度为
D[j]=Min{D[i]|vi∈V-S}, S初值为{v0}
的路径就是从v0出发的长度最短的一条路径。
此路径为(v0, vj)。

那么,下一条长度次短的路径是哪一条呢?
假设该次短路径的终点是vk,可想而知,这条路径或者是(v0, vk),或者是(v0, vj, vk)。

它的长度或者是从v0到vk的弧上的权值,或者是D[j]和从vj到vk的弧上的权值之和。

在一般情况下,下一条长度次短的路径的长度必是
D[j]=Min{D[i]|vi∈V-S}
其中,D[i]或者是弧(v0, vi)上的权值,或者是D[k](vk∈S和弧(vk, vi)上的权值之和。

根据以上分析,可以得到如下描述的算法。

  1. 假设用带权的邻接矩阵arcs表示带权有向图,arcs[i][j]表示弧〈vi, vj〉上的权值。

    若〈vi, vj〉不存在,则置arcs[i][j]为∞(在计算机上可用允许的最大值代替)。

    S为已找到从v0出发的最短路径的终点的集合,它的初始状态S={v0}。

    那么,从v0出发到图上其余各顶点vi可能达到最短路径长度的初值为 D[i]=arcs[LocateVertex(G,v0)][i],
    vi∈V-S

  2. 选择vj,使得 D[j]=Min{D[i]|vi∈V-S} vj就是当前求得的一条从v0出发的最短路径的终点。令S=S∪{vj}。

  3. (3)修改从v0出发到集合V-S上任一顶点vk可达的最短路径长度。如果 D[j]+arcs[j][k]<D[k] 则修改D[k]为
    D[k]=D[j]+arcs[j][k] 重复操作步骤(2)和步骤(3)共n-1次。

由此求得从v0到图上其余各顶点的最短路径是依路径长度递增的序列。

用C++语言描述的Dijkstra算法如下:

#include <iostream>
using namespace std;const int MAXW = 30000;
const int MaxVertexNum = 30;
typedef int VertexType;
class MGraph
{public:void CreateGraph();void ShortestPath_Dij(int v0);void Print_Path_Dij(int v0);private:int vertexnum;VertexType vertexs[MaxVertexNum];int edgenum;int P[MaxVertexNum];int D[MaxVertexNum];int arcs[MaxVertexNum][MaxVertexNum];
};void MGraph::CreateGraph()
{cout << "请输入节点数和边条数" << endl;cin >> vertexnum >> edgenum;for (int i = 0; i < vertexnum; i++)for (int j = 0; j < vertexnum; j++)arcs[i][j] = MAXW;cout << "请依次输入按序号0到n顶点的中存储的信息" << endl;for (int i = 0; i < vertexnum; i++){cin >> vertexs[i];}cout << "下面输入边的信息" << endl;for (int i = 0; i < edgenum; i++){int v1, v2, w;cout << "输入边<i,j>对应的顶点序号i,j,然后再输入该边的权值" << endl;cin >> v1 >> v2 >> w;arcs[v1][v2] = w;}
}void MGraph::ShortestPath_Dij(int v0)
{bool f[MaxVertexNum];for (int v = 0; v <vertexnum; v++){f[v] = false;D[v] = arcs[v0][v];P[v] = -1;if (D[v] < MAXW) P[v] = v0;}D[v0] = 0;f[v0] = true;for (int i = 0; i < vertexnum; i++){int v = -1;int min = MAXW;for (int w = 0; w < vertexnum; w++)if (!f[w] && D[w] < min){v = w;min = D[w];}if (v == -1) break;f[v] = true;for (int w = 0; w < vertexnum; w++){if (!f[w] && (min + arcs[v][w] < D[w])){D[w] = min+arcs[v][w];P[w] = v;}}}
}void MGraph::Print_Path_Dij(int v0)
{cout << "The shortest path from Vertex:" << v0 << " to the other Vertex:" << endl;for (int v = 0; v < vertexnum; v++){if (P[v] == -1)continue;cout << D[v] << " ";cout << v << "<=";int i = v;while (P[i] != -1){cout << P[i] << "<=";i = P[i];}cout << endl;}
}int main()
{MGraph g;g.CreateGraph();int v0;cin >> v0;g.ShortestPath_Dij(v0);g.Print_Path_Dij(v0);return 0;
}

测试结果:

以上代码存在一点小问题,有时间我会进行修改的,我最新发布的dijkstra的代码是正确的,可以在我的博客主页搜索找一下。

C++ 实现带权有向图的单源点最短路径Dijkstra算法(完整代码)相关推荐

  1. 分支限界法:单源最短路径--dijkstra算法

    单源最短路径–dijkstra算法 前面已经多次介绍过dijkstra算法是贪心算法,是动态规划,实际上可以从分支限界的角度来理解: 分支限界法 分支限界法,实际上就是回溯法,一般意义的回溯法是基于深 ...

  2. JAVA编程求单源最短路径_【算法】单源最短路径——dijkstra算法

    一,概念 单源最短路径 给定一个带权有向图G=(V,E),其中每条边的权是一个实数.另外,还给定V中的一个顶点,称为源.要计算从源到其他所有各顶点的最短路径长度.这里的长度就是指路上各边权之和.这个问 ...

  3. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

  4. C++ 实现带权有向图的每对顶点之间的最短路径Floyd算法(完整代码)

    基本思想是: 假设求从顶点vi到vj的最短路径. 如果从vi到vj有弧,则从vi到vj存在一条长度为arcs[i][j]的路径,该路径不一定是最短路径,尚需进行n次试探. 首先考虑路径(vi, v0, ...

  5. 图算法:2、计算带有负权值的单源最短路径:Bellman-Ford算法

    原文地址:http://www.wutianqi.com/?p=1912 相关文章: 1.Dijkstra算法: http://www.wutianqi.com/?p=1890 2.Floyd算法: ...

  6. 数据结构与算法—单源最短路径dijkstra算法

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  7. 单源顶点最短路径java_单源最短路径-Dijkstra 算法

    Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问题:求a点到各个点的最短距离,如下图 ...

  8. dijkstra 算法_数据结构与算法—单源最短路径dijkstra算法

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  9. 单源最短路径Dijkstra算法的思想、详细步骤、代码

    目录 一.算法思想 二.算法详细步骤 三.伪代码 + C++代码 四.算法复杂度分析 五.算法改进 六.应用案例 一.算法思想 1.Dijkstra 算法是用来求解单源最短路径问题的经典算法,其本质上 ...

最新文章

  1. 网页分享插件 share.js 国外常用
  2. nginx重写rewrite的[emerg] unknown directive
  3. Flume 1.7 源码分析(二)整体架构
  4. Linux主流架构运维工作简单剖析
  5. 【渝粤教育】国家开放大学2018年秋季 0692-22T化工设备机械基础 参考试题
  6. 群晖ffmpeg_群晖Video station支持DTS和EAC3
  7. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(2)
  8. 等保2.0多少分合格?70分还是80分呢?
  9. PCB Layout的10个细节
  10. 蓝桥杯之单片机学习(十八)——555定时器与频率测量
  11. python之dataframe写excel合并单元格_python之DataFrame实现excel合并单元格
  12. php 打印出心形,利用php输出不同的心形图案_PHP
  13. 微信小程序支付V3(Java版)
  14. 如何设置用计算机程序打开方式,WPS安装后怎么设置为文档的默认打开方式的方法...
  15. win10系统下忘记登录密码最简单重置方法(无需U盘),本人实践!
  16. self-redemption
  17. 单片机控制74hc595驱动4个单数码管计数显示
  18. mysql排列组合实现_排列-组合的代码实现
  19. win10关闭自带键盘(亲测有用)
  20. 大数据实战项目之电商数仓(一)

热门文章

  1. ArcGIS实验教程——实验二十七:时态数据可视化----以飓风路径为例
  2. 「博客之星」评选,互投5星,留链必投
  3. Android之部分手机(oppo r9s)安装app出现崩溃问题解决办法
  4. 《零基础看得懂的C++入门教程 》——(3)表达式花样挺多鸭
  5. 【C语言简单说】二十:指针基础
  6. 计算机辅助翻译的启示,翻译单位研究对计算机辅助翻译启示.PDF
  7. 我是永远不可能出轨的,除非......
  8. 看了《隐秘的角落》才知道,掉头发有多可怕!10个掉头发最快的专业!快看看你中枪了没有!...
  9. 原来历史人物的英文名竟然叫这些,太好笑了吧哈哈哈哈哈
  10. 大数据告诉你,中国女人有多勤奋