最短路问题之Dijkstra算法
题目:
在上一篇博客的基础上,这是另一种方法求最短路径的问题。
Dijkstra(迪杰斯特拉)算法:找到最短距离已经确定的点,从它出发更新相邻顶点的最短距离。此后不再关心前面已经确定的“最短距离已经确定的点”。
Dijkstra算法采用的是一种贪心的策略,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点 s 的路径权重被赋为 0 (dis[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把dis[m]设为w(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。
初始时,集合T只有顶点s。然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点,然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。
代码:
import java.util.HashSet;
import java.util.Set; public class 图的最短路问题_Dijkstra {
public static void main(String[] args) {
int s = 1;
int[] shortestPath = shortestPath(s); for (int i = 0; i < prev.length; i++) {
System.out.println((char) ('A' + s) + "到" + (char) ('A' + i) + "的路径");
System.out.print((char) ('A' + i) + "<-");
int j = prev[i];
while (j != s) {
System.out.print((char) ('A' + j) + "<-");
j = prev[j];
}
System.out.print((char) ('A' + j));
System.out.println(":" + shortestPath[i]);
}
} static int[] prev; /**
* 求起点到各顶点的最短距离
*
* @param s 起点
* @return
*/
private static int[] shortestPath(int s) {
// 顶点个数
int n = graph.length;
// 记录每个点的前驱
prev = new int[n];
// 一定要初始化,源点的前驱是自身
prev[s] = s;
// 记录s到各顶点的最短距离
int[] d = new int[n];
d[s] = 0;// 自己到自己的距离为0
// 记录已经找到最短距离的顶点
Set<Integer> T = new HashSet<>();
T.add(s); /*-第一步:直接可达的顶点,用距离来初始化d,d[s]=0,可直达的把距离记录下来作为待定值-*/
for (int i = 0; i < n; i++) {
if (i != s && graph[s][i] == 0)
d[i] = Integer.MAX_VALUE;// 不可直达的顶点,先以最大整数作为待定值
if (i != s && graph[s][i] > 0) {
d[i] = graph[s][i]; // 可直达的顶点,以直达距离作为待定值
prev[i] = s; // 可直达的顶点,其前驱是源点
}
}
// Util.print(d); while (T.size() < n) {
/*-第二步:从待定的距离表中找到最小值,这个值可以作为确定值,为什么?-*/
int min = minIndex(d, T);
T.add(min);
if (T.size() == n)
break;
/*-第三步,看这个新确定的顶点的出度,看看从源点出发是经过这个顶点到其邻居近还是直达更近,如果更近就要更新-*/
// 扫描index的邻居
for (int neighbor = 0; neighbor < n; neighbor++) {
int cost = graph[min][neighbor];
// 更新
if (cost > 0 && d[neighbor] > d[min] + cost) {
d[neighbor] = d[min] + cost;
prev[neighbor] = min; // 更新最短路后,要更新i这个点的前驱
}
}
}
return d;
} /**
* 从未确定的点里面找一个最小的
*
* @param d
* @param t 已确定了最短距离的顶点集
* @return
*/
private static int minIndex(int[] d, Set<Integer> t) {
int index = -1;
int min = Integer.MAX_VALUE;
for (int i = 0; i < d.length; i++) {
if (!t.contains(i) && d[i] < min) {
min = d[i];
index = i;
}
}
return index;
} static int[][] graph = {
{ 0, 2, 5, 0, 0, 0, 0 },
{ 2, 0, 4, 6, 10, 0, 0 },
{ 5, 4, 0, 2, 0, 0, 0 },
{ 0, 6, 2, 0, 0, 1, 0 },
{ 0, 10, 0, 0, 0, 3, 5 },
{ 0, 0, 0, 1, 3, 0, 9 },
{ 0, 0, 0, 0, 5, 9, 0 }
};
}
结果:

例题,POJ-1502
最短路问题之Dijkstra算法的更多相关文章
- 7-9 旅游规划 (25 分)(Dijkstra算法)
题意: 思路:单源最短路问题,Dijkstra算法搞定就可以了,因为要找出最便宜的最短路,所以需要在更新最短距离的时候加一个条件(即当最短距离相等的时候,如果该路径的花费更小,就更新最小花费)就可 ...
- dijkstra算法解决单源最短路问题
简介 最近这段时间刚好做了最短路问题的算法报告,因此对dijkstra算法也有了更深的理解,下面和大家分享一下我的学习过程. 前言 呃呃呃,听起来也没那么难,其实,真的没那么难,只要弄清楚思路就很容易 ...
- HDU 1874 畅通工程续-- Dijkstra算法详解 单源点最短路问题
参考 此题Dijkstra算法,一次AC.这个算法时间复杂度O(n2)附上该算法的演示图(来自维基百科): 附上: 迪科斯彻算法分解(优酷) problem link -> HDU 1874 ...
- 最短路问题---Dijkstra算法学习
Dijkstra又称单源最短路算法,就从一个节点到其他各点的最短路,解决的是有向图的最短路问题 此算法的特点是:从起始点为中心点向外层层扩展,直到扩展到中终点为止. 该算法的条件是所给图的所有边的权值 ...
- 最短路问题 Dijkstra算法- 路径还原
// 路径还原 // 求最短路,并输出最短路径 // 在单源最短路问题中我们很容易想到,既然有许多条最短路径,那将之都存储下来即可 // 但再想一下,我们是否要把所有的最短路径都求出来呢? // 实际 ...
- 最短路问题Dijkstra算法
Dijkstra算法可以解决源点到任意点的最短距离并输出最短路径 准备: 建立一个距离数组d[ n ],记录每个点到源点的距离是多少 建立一个访问数组v[ n ],记录每个点是否被访问到 建立一个祖先 ...
- [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...
- 最短路径算法之Dijkstra算法(java实现)
前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知 ...
- Dijkstra算法求解最短路径分析
最短路径是图论算法中的经典问题.图分为有向图.无向图,路径权值有正值.负值,针对不同的情况需要分别选用不同的算法.在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题. 针对无向图,正权 ...
随机推荐
- Java JWT: JSON Web Token
Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand libr ...
- 修改LINUX的时区。
新装的机器(redhat7)有几台时区不对: 百度了之后找到了以下解决方法输入 tz 依次选择Asia China east China Yes 1 然后 export TZ 新开对话发现 ...
- Go 语言之三驾马车
interface Go是一门面向接口编程的语言,interface的设计自然是重中之重.Go中对于interface设计的巧妙之处就在于空的interface可以被当作"Duck" ...
- Dubbo中集群Cluster,负载均衡,容错,路由解析
Dubbo中的Cluster可以将多个服务提供方伪装成一个提供方,具体也就是将Directory中的多个Invoker伪装成一个Invoker,在伪装的过程中包含了容错的处理,负载均衡的处理和路由的处 ...
- 排序1,2......n的无序数组,时间复杂度为o(n),空间复杂度为o(1)
#include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _T ...
- VIJOS-P1635 城市连接
嘿嘿嘿,逆向spfa,貌似不难... #include <cstdio> #include <algorithm> #include <cmath> #includ ...
- Python3字符串替换replace(),translate(),re.sub()
Python3的字符串替换,这里总结了三个函数,replace()和translate()和re.sub() replace() replace() 方法把字符串中的 old(旧字符串) 替换成 ne ...
- ReentrantLock和读写锁
在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...
- Python之父重回决策层
在Guido van Rossum(吉多·范罗苏姆)卸任BDFL(“终身仁慈独裁者”)一职半年多之后,Python社区迎来了新的治理新方案:指导委员会模式,而经过投票Guido van Rossum也 ...
- python接口自动化(二十一)--unittest简介(详解)
简介 前边的随笔主要介绍的requests模块的有关知识个内容,接下来看一下python的单元测试框架unittest.熟悉 或者了解java 的小伙伴应该都清楚常见的单元测试框架 Junit 和 T ...