有向图的单源非负最短路径算法-dijkstra算法

dijkstra应用范围:

图中各边权值非负。

最短路径在现实中应用很广,比如在地图上找出最短路径等,这个算法很重要。

算法思想很简单,它不是找特定节点対之间的最短路径,它是找出源节点到所有其他节点的最短路径。

怎么找呢?

所需额外参数:path[] 记录路径。 dist[] 记录路径长度, visited [] 标记已找到最短路径的节点。

第一步初始化,

将源节点visited标记为true, 并将其直连边长度,更新到dist[]数组。

其次要明白所有路径中最短的路径是哪一条?

肯定是源节点直连边(路径长度为1)中最短的那一条。

第二条呢?

必然是直连边或者第一条最短路径再扩一边中的最小边。

第N条呢?

如果我们把以求出最短路径的点标记为true,那么可以证明,下一条最短路径必然是true点再扩一条边中的最短边所组成的路径。

然后我们依次找下去,找N-1次,就可以找到源节点到所有目标节点的最短路径。

想要找出所有节点间的最短路径,变换源节点,重复N次即可。

下面给出Java代码,图用邻接矩阵存储:

 1 public int minPath(int source, int target){
 2         if (source == target){
 3             System.out.println("(" + source + " " + target + ")");
 4             return 0;
 5         }
 6         int[] path = dijkstra(source);
 7         int result = 0;
 8         String way = "";
 9         while (-1 != path[target]){
10             way = "(" + path[target] + " " + target + ") " + way;
11             result += graph[path[target]][target];
12             target = path[target];
13         }
14         System.out.println(way);
15         return result;
16     }
17     private int[] dijkstra(int vertex){
18        int[] path = new int[numVertices];
19        boolean[] visited = new boolean[numVertices];
20        int[] lenPath = new int[numVertices];
21
22        // initial
23        int neighbor = getFirstNeighbor(vertex);
24        while (neighbor != -1){
25            lenPath[neighbor] = graph[vertex][neighbor];
26            neighbor = getNextNeighbor(vertex,neighbor);
27        }
28        for (int i = 0; i < numVertices; i++) {
29            if (lenPath[i] == 0){
30                lenPath[i] = 1000;
31                path[i] = -1;
32            }else{
33                path[i] = vertex;
34            }
35        }
36        visited[vertex] = true;
37
38         // find min pathLen in unvisited vertex.
39        for (int i = 0; i < numVertices-1; i++) {
40            int min = vertex;
41            for (int j = 0; j < numVertices; j++) {
42                if (visited[j] == false && lenPath[j] < lenPath[min]){
43                    min = j;
44                }
45            }
46            if (min == vertex){
47                return path;
48            }
49            visited[min] = true;
50            for (int j = 0; j < numVertices; j++) {
51                if (visited[j] == false && lenPath[j] > lenPath[min] + graph[min][j]){
52                    lenPath[j] = lenPath[min] + graph[min][j];
53                    path[j] = min;
54                }
55            }
56        }
57        return path;
58     }
时间: 2024-10-01 04:22:45

有向图的单源非负最短路径算法-dijkstra算法的相关文章

有向图单源非负权值回路最短路径——BellmanFord算法

BellmanFord算法是一种暴力求解算法O(N3),它考虑所有情况,所以可以允许边的权值为负.(不过不允许出现负权值回路,因为那样会出现无限小) 之所以说它暴力,是因为它求出了每个节点所有长度为1的路径,再求所有长度为2的路径,并更新最短路径数组dist[]和path[],如此迭代直至求到长度n-1的路径.(n为图节点个数) 整体来看,每个节点纵向比较,从1到n-1长度的路径中取最小值作为最终路径长度. 因为它考虑了所有情况,所以负边也可以算出. 因为暴力,复杂度比Dijkstra高一个数量

P103 单源最短路问题 第三种Dijkstra算法

///通过队列,找出最小的dis[]值,取出配对的vertex值. /// stack priority_queue set struct edge { int to; int cost; } ; vector <edge>G[MZX_V];///表 typedef pair<int ,int > Pa;///Pa.second是点的编号 Pa.first是到该点的最短距离 int dis[MAX_V]; void Dijkstra( ) { priority_queue<

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

Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定.算法反复选择具有最短路径估计的顶点u,并将u加入到S中,对u 的所有出边进行松弛.如果可以经过u来改进到顶点v的最短路径的话,就对顶点v的估计值进行更新. 如上图,u为源点,顶点全加入到优先队列中. ,队列中最小值为u(值为0),u出队列,对u的出边进行松弛(x.v.w),队列最小值

图的单源最短路径:Dijkstra算法实现

本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法. 算法核心思想参见维基.简而言之,设集合S存放已经求出了最短路径的点.初始状态S中只有一个点v0,之后每求得v0到vn的最短路径,就会更新v0到所有vn邻接的点的一致的最短路径(不一定是最终的最短路径),如此重复,每次会确定v0到一个点的最短路径,确定好的点加入S中,直至所有点进入S结束.在本文中

hdu 2680 最短路径(dijkstra算法+多源最短路径单源化求最小值)

Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7062    Accepted Submission(s): 2301 Problem Description One day , Kiki wants to visit one of her friends. As she is liable

单源最短路径(dijkstra算法)php实现

做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi...Vk)也必定是从i到k的最短路径.Dijkstra是以最短路径长度递增,逐次生成最短路径的算法.例如:对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+cost[i][j]}.假设G

单源最短路 狄克斯特拉算法

一般形式的用邻接矩阵来实现dijkstra效率比较低,我这里直接记录的是用邻接表的方法以及用优先队列加以应用. 首先解释什么是dijkstra算法 dijkstra算法 dijkstra算法适用于求单源最短路,即可以求出起点到其余各点之间的最短路.它的算法实现是一个不断更新的过程. 举一个最简单的例子,假设有这么一个图,红色表示权值,黑色表示4个点以及路径,我们假设起点为1,用d[i]来表示1到i的最短路,那么在第一轮的时候,d[2]=1,d[3]=1,d[4]=5,再下一轮的时候会对这个情况进

有向有权图的最短路径算法--Dijkstra算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法, 在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算

最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)

一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine-->mine..... 那么,就存在这样一个问题:给定一个单词作为起始单词(相当于图的源点),给定另一个单词作为终点,求从起点单词经过的最少变换(每次变换只会变换一个字符),变成终点单词. 这个问题,其实就是最短路径问题. 由于最短路径问题中,求解源点到终点的最短路径与求解源点到图中所有顶点的最短路径复