最短路径算法―Dijkstra(迪杰斯特拉)算法分析与实现(
- 格式:doc
- 大小:18.00 KB
- 文档页数:7
Dijkstra最短路径算法的实现及优化 施培港 厦门信息港建设发展股份有限公司 厦门市槟榔路1号联谊广场五层 361004 Email:spg@xminfoport.com 摘要:最短路径算法种类繁多,比较有名的算法包括:Dijkstra算法、Ford算法、Floyd算法、Moore算法、A*算法、K值算法,而即使同一种算法也有多种不同的实现方式。
本文就Dijkstra算法的两种实现方式做一定的分析,并采用一种新的实现方法达到对算法优化的目的。
关键字:Dijkstra算法 最短路径 网络分析 地理信息系统(GIS) 1. 何谓最短路径 所谓最短路径就是网络中两点之间距离最短的路径,这里讲的距离可以是实际的距离,也可以引申为其它的度量,如时间、运费、流量等。
因此,从广义上讲,最短路径算法就是指从网络中找出两个点之间最小阻抗路径的算法。
2. Dijkstra算法介绍 Dijkstra算法本身是一种贪婪算法,它通过分步的方法来求最短路径。
首先,初始产生源点到它自身的路径,其长度为零,然后在贪婪算法的每一步中,产生一个到达新的目的顶点的最短路径。
其算法描述如下(算法中以有向图表示网络结构): 对于有向图G =(V,E),图中有n个顶点,有e条弧,其中V为顶点的集合,E为弧的集合,求源点VS到终点VT的最短路径。
(1) 用带权的邻接矩阵L来表示有向图,L(X,Y)表示弧<X,Y>的权值,若弧<X,Y>不存在,则设L(X,Y)=∞;用D(X)表示源点VS到顶点X的距离,除源点VS的值为0外,其余各点设为∞;用S表示已找到的从源点VS出发的最短路径的顶点的集合,其初始状态为空集;用V-S表示未找到最短路径的顶点的集合; (2) 选择源点VS做标记,令Y = VS,S = S ∪ {VS}; (3) 对于V-S中各顶点, 若D(X) > D(Y) + L(Y,X),则修改D(X)为 D(X) = D(Y) + L(Y,X) 其中Y是己确定作标记的点; (4) 选择Vj,使得D(j) = min{ D(i) | Vi ∈ V-S } 若D(j)为∞,则说明VS到V-S中各顶点都没有通路,算法终止;否则,Vj就是当前求得的一条从源点VS出发的最短路径的终点,对Vj做标记,令Y = Vj,并把Vj放入集合S中,即令S = S ∪ {Vj}; (5) 如果Y等于VT,则说明已经找到从VS到VT的最短路径,算法终止;否则,转到3继续执行。
路径优化数学模型Dijkstra原理:1.1Dijkstra算法概述:Dijkstra算法是由E.w.Dijkstra于1959年提出的一个适用于所有弧的权为非负的最短路径算法。
它可给出从某固定结点到图中其它所有结点的最短距离,时间复杂度为n2,其中n为结点个数。
1.2Dijkstra算法描述:首先引进辅助变量dist【】,它的每一个分量dist【i】表示已经找到的从开始点V0到每一个终点Vi的最短路径。
它的初态为:如果V0到Vi有弧,则dist【i】为弧的权值,如无弧,则dist【i】为无穷大。
其中,长度为dist【j】=Min{dist【i】vi属于V}的路径是从V0出发的长度最短的一条最短路径,此路径为(v0,vj)。
当按长度递增的顺序来产生各个最短路径的时候,设S为已经求得的最短路径的顶点集合。
可以证明:下一条最短路径或者是弧(v0,vx),或者是中间经过S中的某些顶点,而后到达的vx的路径。
通过反证法,可以得到,下一条最短路径上,不可能有不在S中的结点。
一般情况下,下一条最短路径dist【j】=min{dist【i】vi属于V-S}i。
其中dist【i】的权值或者是(v0,vi)的权值,或者是dist【k】(Vk属于V-S)和弧(vk,vi)上的权值之和。
可以将图中的顶点分为分为两座;S——以求出的最短路径的终点集合(开始为v0);V-S——尚未求出最短路径的顶点集合(开始为V-{v0}的全部结点);按最短路径长度递增的顺序将第二组结点加入到第一组中。
1.3 Dijkstra实现Dijkatra算法的一般步骤如下:(1)g为用邻接矩阵表示的带权图,则garcs【i】【j】表示弧(vi,vj)上的权值。
dist【i】=garcs【v0】【vi】;将v0到其余结点的路径长度初始化为权值。
(2)选择vk,使得dist【vk】=min{dist【i】vi属于V-S}Vk为目前求得的下一条从v0出发的最短路径的终点;(3)修改从v0出发到集合V-S上任意顶点vi的最短路径长度,如果,dist【k】+garcs【k】【i】<dist【i】,那么dist【i】= dist【k】+garcs【k】【i】。
c语言最短路径的迪杰斯特拉算法Dijkstra的算法是一种用于查找图中两个节点之间最短路径的算法。
这个算法可以应用于有向图和无向图,但是它假设所有的边都有正权值,并且不包含负权值的边。
以下是一个简单的C语言实现:c复制代码#include<stdio.h>#define INF 99999#define V 5 // 顶点的数量void printSolution(int dist[]);void dijkstra(int graph[V][V], int src);int main() {int graph[V][V] = { { 0, 4, 0, 0, 0 }, { 4, 0, 8, 11, 7 },{ 0, 8, 0, 10, 4 },{ 0, 11, 10, 0, 2 },{ 0, 7, 4, 2, 0 } };dijkstra(graph, 0);return0;}void dijkstra(int graph[V][V], int src) { int dist[V];int i, j;for (i = 0; i < V; i++) {dist[i] = INF;}dist[src] = 0;for (i = 0; i < V - 1; i++) {int u = -1;for (j = 0; j < V; j++) {if (dist[j] > INF) continue;if (u == -1 || dist[j] < dist[u]) u = j;}if (u == -1) return;for (j = 0; j < V; j++) {if (graph[u][j] && dist[u] != INF && dist[u] + graph[u][j] < dist[j]) {dist[j] = dist[u] + graph[u][j];}}}printSolution(dist);}void printSolution(int dist[]) {printf("Vertex Distance from Source\n"); for (int i = 0; i < V; i++) {printf("%d \t\t %d\n", i, dist[i]);}}这个代码实现了一个基本的Dijkstra算法。
最短路径算法(dijkstra)讲解最短路径算法是计算机科学中一个非常重要且广泛应用的算法,它用于求解网络中节点到节点的最短路径。
本文将介绍 Dijkstra 最短路径算法的基本原理和步骤,并对其进行拓展。
Dijkstra 算法的基本原理是:从起点开始,依次将每个未连接的节点加入已连接的队列中,直到所有节点都被加入队列,并且队列为空。
然后从最后一个节点开始,依次取出队列中的节点,计算每个节点到起点的最短距离,并将这些距离累加到一个距离数组中。
最后,返回距离数组中的最小距离,即最短路径。
下面是 Dijkstra 算法的基本步骤:1. 初始化:- 将起点标记为已连接节点。
- 将起点到所有其他节点的距离设为无穷大。
- 将起点加入到距离队列中。
2. 处理队列:- 从距离队列中取出一个节点,并将其加入到连接表中。
- 计算该节点到起点的最短距离。
- 如果该距离小于当前最小距离,则更新最小距离。
- 将该节点标记为已连接节点。
3. 处理连接表:- 如果所有节点都被标记为已连接节点,则返回起点。
- 如果某个节点没有被标记为已连接节点,且该节点到其他节点的最短距离小于当前最小距离,则更新最小距离。
- 将该节点加入到距离队列中。
下面是针对 Dijkstra 算法的拓展:1. 时间复杂度分析:- Dijkstra 算法的时间复杂度为 O(nlogn)。
- 在最坏情况下,当所有节点的权重都为0时,Dijkstra 算法的时间复杂度为O(n^2)。
2. 非最坏情况下的改进:- 当节点的权重都较小时,Dijkstra 算法使用的是贪心算法,其性能可能会退化为 O(n^2)。
- 针对这种情况,可以使用启发式算法,如 A* 算法或贪心算法,来改进Dijkstra 算法的性能。
3. 扩展应用场景:- Dijkstra 算法可以用于求解单源最短路径问题、单源最短路径问题和无后效性问题。
- Dijkstra 算法还可以用于求解网络中的最小生成树问题和最小生成树问题。
C++⽤Dijkstra(迪杰斯特拉)算法求最短路径算法介绍迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此⼜叫狄克斯特拉算法。
是从⼀个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。
迪杰斯特拉算法主要特点是以起始点为中⼼向外层层扩展,直到扩展到终点为⽌。
Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
算法思想按路径长度递增次序产⽣算法: 把顶点集合V分成两组: (1)S:已求出的顶点的集合(初始时只含有源点V0) (2)V-S=T:尚未确定的顶点集合 将T中顶点按递增的次序加⼊到S中,保证: (1)从源点V0到S中其他各顶点的长度都不⼤于从V0到T中任何顶点的最短路径长度 (2)每个顶点对应⼀个距离值 S中顶点:从V0到此顶点的长度 T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度 依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和应⽤举例(1)题⽬:编写⼀个校园导游程序,为来访的客⼈提供各种信息查询服务。
主要功能:1.设计学校的校园平⾯图,所含景点不少于10个:顶点表⽰景点,边表⽰路径等; 2.为客⼈提供图中任意景点相关信息的查询; 3.为客⼈提供图中任意景点的问路查询,即查询⼈以景点间的⼀条最短路径。
要求:1.设计⼀个主界⾯; 2.设计功能菜单,供⽤户选择 3.有⼀定的实⽤性。
(2)设计思路: 1、该题主要有算法思路以及程序的逻辑思路,⾸先从逻辑思路讲,进⼊程序,⾸先设计⼀个主菜单,选项有景点信息查询,最短路径查询以及显⽰景点的平⾯视图三个⼦菜单,然后根据⽤户的输⼊选择的⼦菜单前的编号,分进⼊不同的⼦菜单;该功能是由if….else if…. 语句实现。
在景点信息查询和最短路径查询⼦菜单下还有⼆级⼦菜 单,都是列出所有景点并在前⾯编号,查询景点信息时,输⼊景点前⾯的编号即可,查询最短路径时,先输⼊起点的编号,再输⼊终点的编号。
最短路径迪杰斯特拉算法
迪杰斯特拉算法是一种常用的最短路径算法,它具有简单的运行流程和较强的处理性能,在多个领域得到了广泛的应用。
本文首先介绍了迪杰斯特拉算法的步骤和核心思想,然后论述了它在求解最短路径问题中的应用,最后简要介绍了它与其他常用算法的不同之处。
迪杰斯特拉算法的步骤主要分为以下几步:
1、给出起始点到其他顶点的最短路径,并将其记录在表格中;
2、遍历路径表,确定距离起始点最近的点;
3、把该点加入到已访问的点的集合中,然后再更新其他未访问的点到起始点的最短路径;
4、重复以上步骤,直到所有的点都被访问过为止。
迪杰斯特拉算法的核心思想是使用一个表记录所有节点到起始节点的最短路径,每次更新记录中的最短路径,直到所有节点都被更新完成为止。
在求解最短路径的实际应用中,迪杰斯特拉算法是最常用的算法之一,因其具有较强的处理性能。
例如,在运输规划中,可以通过迪杰斯特拉算法快速求出总行驶距离最短的路径;在计算机网络中,也可以通过迪杰斯特拉算法求出任意两台主机之间的最短通信路径。
与其他常用算法相比,迪杰斯特拉算法在某些特定情况下具有优越的优势。
例如,由于它可以查找所有可能的路径,因此很适合用于求解有环路的网络系统中的最短路径;在处理复杂网络系统中,迪杰斯特拉算法可以计算出最近的一条路径,不必考虑其他较远的路径,这一特点减少了算法的计算复杂度。
总之,迪杰斯特拉算法是一种具有高效性和适应性的算法,在求解最短路径问题中得到了广泛的应用,具有简单的运行流程以及巨大的处理能力。
最短路dijkstra算法详解最短路问题是图论中的一个经典问题,其目标是在给定图中找到从一个起点到其他所有节点的最短路径。
Dijkstra算法是解决最短路问题的一种常用算法,本文将详细介绍Dijkstra算法的原理、实现以及时间复杂度等相关内容。
一、Dijkstra算法的原理Dijkstra算法是一种贪心算法,其基本思想是从起点开始,逐步扩展到其他节点。
具体而言,Dijkstra算法通过维护一个集合S来记录已经找到了最短路径的节点,以及一个数组dist来记录每个节点到起点的距离。
初始时,S集合为空,dist数组中除了起点外所有节点都被初始化为无穷大。
接下来,重复以下步骤直到所有节点都被加入S集合:1. 从dist数组中选择距离起点最近的未加入S集合的节点u;2. 将u加入S集合;3. 更新与u相邻的未加入S集合的节点v的距离:如果从起点出发经过u可以得到更短的路径,则更新v对应位置上dist数组中存储的值。
重复以上步骤直至所有节点都被加入S集合,并且dist数组中存储了每个节点到起点的最短距离。
最后,根据dist数组中存储的信息可以得到起点到任意节点的最短路径。
二、Dijkstra算法的实现在实现Dijkstra算法时,需要使用一个优先队列来维护未加入S集合的节点,并且每次从队列中选择距离起点最近的节点。
由于C++标准库中没有提供优先队列,因此需要手动实现或者使用第三方库。
以下是一个基于STL堆实现的Dijkstra算法代码示例:```c++#include <iostream>#include <vector>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;vector<pair<int, int>> adj[10001];int dist[10001];void dijkstra(int start) {priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;pq.push(make_pair(0, start));dist[start] = 0;while (!pq.empty()) {int u = pq.top().second;pq.pop();for (auto v : adj[u]) {if (dist[u] + v.second < dist[v.first]) {dist[v.first] = dist[u] + v.second;pq.push(make_pair(dist[v.first], v.first));}}}}int main() {int n, m, start;cin >> n >> m >> start;for (int i = 1; i <= n; i++) {dist[i] = INF;}for (int i = 1; i <= m; i++) {int u, v, w;cin >> u >> v >> w;adj[u].push_back(make_pair(v, w));}dijkstra(start);for (int i = 1; i <= n; i++) {if (dist[i] == INF) {cout << "INF" << endl;} else {cout << dist[i] << endl;}}return 0;}```以上代码中,adj数组用于存储图的邻接表,dist数组用于存储每个节点到起点的最短距离。
Dijkstra最短路径算法⾸先描述⼀下问题:给定⼀个有向图G和源点v,求v0到G中某个顶点u的最短路径。
限定各边上的权值⼤于或等于0。
算法的基本思想很简单:所有的顶点,按照它到源点v的距离,客观上存在⼀个从⼩到⼤的顺序,我们只要按照这个顺序找下去,总有⼀步会找到⽬标顶点u,⽽此时的距离就是u到源点v的距离。
想法简单,但关键是怎么按照“客观存在的⼤⼩顺序”计算各点到源点v的距离呢?我们先简单思考⼀下,按照距离v的远近顺序,v⼀定是排第⼀的,然后呢,排第⼆的⼀定是和v直接相连的点吧,否则总有⼀个点介于排第⼆的点和v之间,⽽它到v的距离肯定也⽐第⼆到v的距离近,那这个第⼆就有些名副其实了。
⽐较⿇烦的是,排第三的点在哪⾥?利⽤递归的想法就会发现,排第三的点应该从那些和v直接相连,或者和第⼆名直接相连的点中去寻找,否则第三名就会名副其实了。
总结⼀下,需要找第n个点时,只需要在那些和前n-1个点直接相连的点⾥⾯找就⾏了。
Dijkstra算法的具体实现⽅法为:1.设置两个顶点的集合T和S:a) S中存放已找到最短路径的顶点,初始时,集合S中只有⼀个顶点,即源点v0;b) T中存放当前还未找到最短路径的顶点;2.在T集合中选取当前长度最短的⼀条最短路径(v0,…,vk),从⽽将vk加⼊到顶点集合S中,并修改源点v0到T中各顶点的最短路径长度;重复这⼀步骤,直到所有的顶点都加⼊到集合S中,算法就结束了。
下⾯给个⽤Dijkstra计算最短路径的例⼦1)⾸先求出长度最短的⼀条最短路径,即顶点0到顶点2的最短路径,其长度为5,其实就是顶点0到其他各顶点的直接路径中最短的路径(v0→v2)。
2)顶点2的最短路径求出来以后,顶点0到其他各顶点的最短路径长度有可能要改变。
例如从顶点0到顶点1的最短路径长度由∞缩短为20,从顶点0到顶点5的最短路径长度也由∞缩短为12。
这样长度次短的最短路径长度就是在还未确定最终的最短路径长度的顶点中选择最⼩的,即顶点0到顶点5的最短路径长度,为12,其路径为(v0→v2→v5)。
利用Dijkstra算法计算最短路径摘要福格环游地球问题是一个十分典型的最短路径求解问题,题设给出了当时世界上主要交通网络图及交通通畅的城市之间来往所需时长,并限定了福格的出行方向(福格选择的是往东走),给出起止地点后要求找出福格环游世界天数最短的最佳路径。
我们认为,这个问题的实质在于最短路径的求解和优化。
我们对比图论中的多种最短路径算法,决定利用Dijkstra算法解决这个问题。
由于Dijkstra算法要求输入图G的关联矩阵,且图G为二维赋权图,而题中给出的地图可看成是三维环状地图,因此,我们对题设地图做相关处理,将其从起点处“切断”并展开为二维图,然后根据此图建立关联矩阵。
同时,我们考虑到最短路径可能会与切断线有交点,在切断线以西找出若干地点一分为二,修改关联矩阵。
对于题目中缺失的两处数据,本文将以当时的交通数据为基础,经过合理的数据处理,结合Google Earth测距软件与题目数据的合理类比,补充缺失数据,完成关联矩阵。
得到关联矩阵后,我们分别以伦敦、纽约和上海作为起点,调整关联矩阵起点和终点,用matlab编程进行求解得到最短环游时间和最短路径,进而判断出所选择的路径是否能让他赢得赌注。
根据我们的求解结果,在这三个城市,福格均能在80天内环游地球,赢得赌注。
本文进一步对此种算法的优缺点、灵敏度与推广性进行了分析,同时初步提出了两种优化方法。
关键词:最短路径算法 dijkstra算法算法优化一、问题重述儒勒•凡尔纳的著名小说《环游世界80天》中,英国绅士福格在伦敦与人打赌能够在80天内环游世界,这在当时的1872年是一个了不起的壮举。
当时最快的旅行方式是火车和轮船,然而世界上大部分地区还是靠马车、大象、驴子或者步行来旅行。
下面是一个从伦敦环游世界不同路线的交通网络图,福格选择的是往东走,每段路线所需要的天数显示在图上(见附录一),旅行的时间基于1872年能采用的旅行方式以及距离。
我们将解决以下问题:1.我们将设计一个算法为福格选择一条最佳路径,即环游世界天数最短,并判断所选择的路径是否能让他赢得赌注。
《求解最短路径:应用迪杰斯特拉算法》一、介绍Dijkstra算法的概念和基本原理Dijkstra算法是一种用于解决最短路径问题的算法,它由荷兰计算机科学家Edsger Dijkstra在1959年发明,用于求解从源点到其他所有结点的最短路径。
它的基本原理是:在一张图中,从源点到每一个结点的最短路径是从源点开始,经过最少的边到达每一个结点的路径。
Dijkstra算法的实现过程中,首先要建立一个有向图,该图由顶点和边组成,每条边都有一个权值,表示从一个顶点到另一个顶点的距离。
然后,从源点开始,每次选择最小权值的边,继续查找下一个顶点,直到找到终点。
最后,将所有路径之和求出,即为源点到目标点的最短路径。
举例来说,假如有一张有向图,其中有A,B,C,D四个结点,以及AB,AC,BD,CD四条边,其中AB,AC,BD边的权值分别为2,3,1,CD边的权值为4。
如果要求求出从A到D的最短路径,则可以使用Dijkstra算法,首先从A出发,选择权值最小的边,即BD,则A-B-D的路径长度为3,接着从B出发,选择权值最小的边,即CD,则A-B-D-C的路径长度为7,因此,从A到D的最短路径为A-B-D,路径长度为3。
Dijkstra算法的优点是算法简单,实现方便,时间复杂度低,它可以用于解决路径规划,车辆调度,网络路由等问题,同时,它也可以用于解决复杂的最短路径问题。
因此,Dijkstra算法在计算机科学中有着重要的应用价值。
二、讨论Dijkstra算法的应用及其优势Dijkstra算法是一种用于解决最短路径问题的算法,它的应用和优势非常广泛。
首先,Dijkstra算法可以用于解决交通路网中的最短路径问题。
例如,在一个城市的交通路网中,如果一个乘客要从一个地方到另一个地方,那么他可以使用Dijkstra算法来查找最短的路径。
这样可以节省乘客的时间和金钱,也可以减少拥堵。
此外,Dijkstra算法还可以用于解决计算机网络中的最短路径问题。
Dijkstra(迪杰斯特拉算法是典型的最短路径路由算法,用于计算一个节点到其他所有
节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率
低。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有
详细的介绍,如数据结构,图论,运筹学等等。
其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集
合S当且仅当从源到该顶点的最短路径长度已知。
初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的
路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径
长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S
中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从
源到所有其它顶点之间的最短路径长度。
例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径
的过程列在下表中。
Dijkstra算法的迭代过程:
主题好好理解上图!
以下是具体的实现(C/C++:
1. /***************************************
2. * About: 有向图的Dijkstra算法实现
3. * Author: Tanky Woo
4. * Blog: www.WuTianQi.com
5. ***************************************/
6.
7. #include
8. using namespace std;
9.
10. const int maxnum = 100;
11. const int maxint = 999999;
12.
13.
14. void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum]
15. {
16. bool s[maxnum]; // 判断是否已存入该点到S集合中
17. for(int i=1; i<=n; ++i
18. {
19. dist[i] = c[v][i];
20. s[i] = 0; // 初始都未用过该点
21. if(dist[i] == maxint
22. prev[i] = 0;
23. else
24. prev[i] = v;
25. }
26. dist[v] = 0;
27. s[v] = 1;
28.
29. // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
30. // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最
短路径长度
31. for(int i=2; i<=n; ++i
32. {
33. int tmp = maxint;
34. int u = v;
35. // 找出当前未使用的点j的dist[j]最小值
36. for(int j=1; j<=n; ++j
37. if((!s[j] && dist[j]
38. {
39. u = j; // u保存当前邻接点中距离最小的点的号码
40. tmp = dist[j];
41. }
42. s[u] = 1; // 表示u点已存入S集合中
43.
44. // 更新dist
45. for(int j=1; j<=n; ++j
46. if((!s[j] && c[u][j]
47. {
48. int newdist = dist[u] + c[u][j];
49. if(newdist < dist[j]
50. {
51. dist[j] = newdist;
52. prev[j] = u;
53. }
54. }
55. }
56. }
57.
58. void searchPath(int *prev,int v, int u
59. {
60. int que[maxnum];
61. int tot = 1;
62. que[tot] = u;
63. tot++;
64. int tmp = prev[u];
65. while(tmp != v
66. {
67. que[tot] = tmp;
68. tot++;
69. tmp = prev[tmp];
70. }
71. que[tot] = v;
72. for(int i=tot; i>=1; --i
73. if(i != 1
74. cout << que[i] << " -> ";
75. else
76. cout << que[i] << endl;
77. }
78.
79. int main(
80. {
81. freopen("input.txt", "r", stdin;
82. // 各数组都从下标1开始
83. int dist[maxnum]; // 表示当前点到源点的最短路径长度
84. int prev[maxnum]; // 记录当前点的前一个结点
85. int c[maxnum][maxnum]; // 记录图的两点间路径长度
86. int n, line; // 图的结点数和路径数
87.
88. // 输入结点数
89. cin >> n;
90. // 输入路径数
91. cin >> line;
92. int p, q, len; // 输入p, q两点及其路径长度
93.
94. // 初始化c[][]为maxint
95. for(int i=1; i<=n; ++i
96. for(int j=1; j<=n; ++j
97. c[i][j] = maxint;
98.
99. for(int i=1; i<=line; ++i
100. {
101. cin >> p >> q >> len;
102. if(len < c[p][q] // 有重边
103. {
104. c[p][q] = len; // p指向q
105. c[q][p] = len; // q指向p,这样表示无向图
106. }
107. }
108.
109. for(int i=1; i<=n; ++i
110. dist[i] = maxint;
111. for(int i=1; i<=n; ++i
112. {
113. for(int j=1; j<=n; ++j
114. printf("%8d", c[i][j];
115. printf("\n";
116. }
117.
118. Dijkstra(n, 1, dist, prev, c;
119.
120. // 最短路径长度
121. cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;
122.
123. // 路径
124. cout << "源点到最后一个顶点的路径为: ";
125. searchPath(prev, 1, n;
126. }
复制代码
输入数据:
5
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
输出数据:
999999 10 999999 30 100
10 999999 50 999999 999999
999999 50 999999 20 10
30 999999 20 999999 60
100 999999 10 60 999999
源点到最后一个顶点的最短路径长度: 60
源点到最后一个顶点的路径为: 1 -> 4 -> 3 -> 5