Dijkstra算法求最短路

Dijkstra算法可以在图中寻找一个节点(称为“源节点”)到所有其它节点的最短路径。

文章目录

前言

一、Dijkstra算法是什么?

二、问题介绍

三、朴素版Dijkstra算法

1.图的存储

2.算法实现

四、使用步骤

1.代码如下(示例):

2.读入数据

3.代码运行结果

总结


前言

Dijkstra算法可以在图中寻找一个节点(称为“源节点”)到所有其它节点的最短路径。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Dijkstra算法是什么?

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

Dijkstra算法主要解决单源最短路径问题。

注:Dijkstra算法无法解决寻找当有权图中权值为负数的最短路。

二、问题介绍

给定一个 n个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出 1 号点到 n 号点的最短距离,如果无法从 11号点走到 n 号点,则输出 −1−1。

输入格式:

第一行包含整数 n和 m。

接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x到点 y的有向边,边长为 z。

输出格式:

输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 −1。

数据范围:

1≤n≤500
1≤m≤10^5
图中涉及边长均不超过10000。

三、朴素版Dijkstra算法

1.图的存储

无向图是特殊的有向图,故用Dijkstra算法处理问题我们只用考虑有向图即可。

朴素版Dijkstra算法常用于解决稠密图即图的边数比较多的情况,稠密图用邻接矩阵来存储,稀疏图通常用邻接表存储。

邻接矩阵存储图,我们通过一个二维数组map,行数和列数都对应点的个数,当1结点有一条指向2结点的边,且权值是5是,那么我们就设置map[1][5] = 5即可。

图1.1 图用邻接矩阵存储模拟

2.算法实现

 图2.1思路模拟

这个题存在重边和自环,因为我们是求最短路,那么自环就不用考虑,重边我们存储权值小的边即可。

我们引入邻接矩阵map来存储地图,初始化当i=j的时候初始化为0,然后有重边的话要最小的值,其余的初始化为0x3f3f方便后续dist数组中比较最小值,同时引入n表示结点的个数,m表示边数,一维数组dist表示起点1到第i个点的最小距离。对dist数组进行初始化,dist[1]=0即第一个顶点自身不需要走。然后剩余值初始化为0x3f3f。

注:0x3f3f是16383,超过10^5次方。

同时引入一维数组flag,如果这个点被找到了最短距离,设置为true。

接下来我们遍历n次,即n个点,第一次遍历然后找到在未确定找到最小距离的点中找到离第一个点最近的点,本次找到的肯定是1这个点本身,然后用1这个点初始化dist数组,那么此时dist数组内部的值全变成从1这个点直接到各个点的最短距离;第二次循环,我们找到离1这个结点最短距离的点假设是结点t(因为从第一轮循环1结点肯定是1结点本身离得最近的点,它会被flag设置为tue,我们后续内层循环遍历的时候就不需要再判断这个点),然后用结点t到各个点的直接距离+地图上的权值(即dp[t]+map[t][j])和原本dist数组1结点到各个结点的最短距离(dist[j])比较取最小值,此时我们就得到了现在这个状态下1结点到各个结点的最短距离。后续重复以上说的过程。注:中间如果没有路径到达这个点,那么dist数组中这个点的值会是0x3f3f。当我们进行第n轮循环,那么此时就是到离第n个结点最近的节点,一定是它本身即t = n(只要出现t=n我们就可以退出循环了,因为此时相当于我们已经找到最短路径了就是此时的dist[n]),那么我们在初始化dist数组之后,dist[n]就是我们从1到n的最短距离。如果我们没有路径到达终点那么当前点会被标记为访问过,会循环找别的离上一个点最近的点。当dist[n]=0x3f3f,说明没有路径能到达最后一个结点,输出-1即可。

注 n >= j >= 1

我们可以模拟一下上述的文字描述的循环过程:

 图2.2dists数组初始化

图2.3第一轮dist数组 

 图2.4第二轮dist数组

图2.4第三轮dist数组 

图2.5第四轮dist 数组

通过dist的值变化我们就发现,当我们找到离上一个结点最近的结点t为n时,就可以直接退出循环了,因为后面dist数组的值就不会再发生变化了。

四、使用步骤

1.代码如下(示例):


import java.io.*;
import java.util.*;
public class 朴素版Dijkstra算法 {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//邻接矩阵存储图static int[][] map;//存储点的个数static int n;//存储边的条数static int m;//从1号点走到第i个点的距离是多少static int[] dist;//表示第i个结点的最短距离是否确定static boolean[] flag;public static void main(String[] args) {Scanner sc = new Scanner(br);n = sc.nextInt();m = sc.nextInt();map = new int[510][510];flag = new boolean[510];for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){map[i][j] = 0x3f3f;if(i == j){map[i][j] = 0;}}}while (m-- > 0){int a = sc.nextInt();int b = sc.nextInt();int c = sc.nextInt();map[a][b] = Math.min(map[a][b],c);}int result = dijkstra();pw.println(result);pw.flush();}public static int dijkstra(){//初始化所有的距离dist = new int[510];dist[1] = 0;for(int i = 2;i <= n;i++){dist[i] = 0x3f3f;}//循环n次for(int i = 0;i < n;i++){int t = -1;for(int j = 1;j <= n;j++){//在未确定最短距离的点中找出上一个已确定最短距离点的距离最小的点if(!flag[j] && (t == -1 || dist[t] > dist[j])){t = j;}}flag[t] = true;//用最短距离t点来更新dist数组中的值for (int j = 1;j <= n;j++){dist[j] = Math.min(dist[j],dist[t]+map[t][j]);}}if(dist[n] == 0x3f3f){return -1;}return dist[n];}
}

2.读入数据

3 3
1 2 2
2 3 1
1 3 4

3.代码运行结果

3

1->2 权值2 2->3权值1

2+1 = 3


总结

代码可能不太好理解,debug几次看一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/1334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的UDEV机制

udev 机制引入&#xff1a; 手机接入Linux热拔插相关 a. 把手机接入开发板 b. 安装adb工具&#xff0c;在终端输入adb安装指令&#xff1a; sudo apt-get install adb c. dmeg能查看到手机接入的信息&#xff0c;但是输入adb devices会出现提醒 dinsufficient permissions for …

【Java】HashMap、HashTable和ConcurrentHashMap的区别

文章目录 区别一、HashMap1.1基本定义与特性1.2工作原理与实现1.3常用方法1.4性能与优化 二、HashTable三、ConcurrentHashMap3.1基本特点3.2实现原理3.3常用方法3.4适用场景3.5性能优化 HashTable、HashMap和ConcurrentHashMap之间的区别主要体现在线程安全、继承关系与实现接…

kaggle 泰坦尼克号2 得分0.7799

流程 导入所要使用的包引入kaggle的数据集csv文件查看数据集有无空值填充这些空值提取特征分离训练集和测试集调用模型 导入需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarni…

从C到JAVA之学习JAVA的第一周笔记

文章目录 java语言概述JDK与JRE编写执行过程第一份java代码解读编写编译运行其他 注释三种注释方法 java API文档关键字标识符数据类型基本数据类型自动类型提升规则引用数据类型 string概述String与基本数据类型的变量间的运算 运算符键盘录入运行控制语句数组定义与静态初始化…

springboot no mapping for.....解决办法

这个问题是由于没有加入对应的GET,POST注解&#xff0c;导致映射失败&#xff0c;加入对应注解就ok了

JDK 11下载、安装、配置

下载 到Oracle管网下载JDK 11&#xff0c;下载前需要登录&#xff0c;否则直接点下载会出现502 bad gateway。 下载页面链接 https://www.oracle.com/hk/java/technologies/downloads/#java11-windows 登录 有些人可能没有Oracle账号&#xff0c;注册也比较慢&#xff0c;有需…

随笔05 我的创作纪念日(512天)

机缘 机缘这事儿&#xff0c;我在随笔系列博文里已经翻来覆去说了不少&#xff0c;这次就不再唠叨了&#xff0c;省得被小伙伴嫌弃成祥林嫂~&#x1f61c; &#x1f338;随笔01 我的创作纪念日&#xff08;128天&#xff09;_newmitbbs-CSDN博客 收获 我这一小片自留地&…

JavaEE 初阶篇-深入了解 File 文件操作(实现文件搜索、非空文件夹删除)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 File 文件概述 2.0 创建 File 类对象的方法 2.1 判断文件类型、获取文件信息的方法 2.2 创建文件、删除文件的方法 2.3 遍历文件夹的方法 3.0 文件搜索与删除 3.1…

WebSocket 快速入门 - springboo聊天功能

目录 一、概述 1、HTTP&#xff08;超文本传输协议&#xff09; 2、轮询和长轮询 3、WebSocket 二、WebSocket快速使用 1、基于Java注解实现WebSocket服务器端 2、JS前端测试 三、WebSocket进阶使用 1、如何获取当前用户信息 2、 后端聊天功能实现 一、概述 HTTP…

PVE grub resue错误修复 lvmid BUG

服务器断电后启动不起来&#xff0c;显示grub resue 找了半天没有找到修复方法。看官方文档有一处Recovering from grub “disk not found” error when booting from LVM 极为类似。https://pve.proxmox.com/wiki/Recover_From_Grub_Failure 下面是处理过程。 使用PVE 6.4启…

Leetcode算法训练日记 | day33

专题九 贪心算法 一、跳跃游戏 1.题目 Leetcode&#xff1a;第 55 题 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 …

机器学习(二)之监督学习

前言&#xff1a; 上一节大概讲解了几种学习方式&#xff0c;下面几张就具体来讲讲监督学习的几种算法。 以下示例中和都是权重的意思&#xff01;&#xff01;&#xff01; 注&#xff1a;本文如有错误之处&#xff0c;还请读者指出&#xff0c;欢迎评论区探讨&#xff01; 1…

MATLAB实现图片栅格化

MATLAB实现图片栅格化 1.读取图片&#xff1a;首先&#xff0c;你需要使用imread函数读取要栅格化的图片。 2.设置栅格大小&#xff1a;确定你希望将图片划分成的栅格大小&#xff0c;即每个栅格的宽度和高度。 3.计算栅格数量&#xff1a;根据图片的总尺寸和栅格大小&#…

Compose 布局

文章目录 Compose 布局ColumnColumn属性使用 RowRow属性使用 BoxBox属性使用 ConstraintLayoutLazyColumnLazyColumn属性使用使用多类型使用粘性标题回到顶部 LazyRowLazyRow属性使用 LazyVerticalGridLazyVerticalGrid属性使用 Compose 布局 Column Compose中的”垂直线性布…

F-logic DataCube3 SQL注入漏洞复现(CVE-2024-31750)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/pr_monitor/getting_index_data.php 接口处存在SQL注入漏洞,未经身份验证的攻击者可通过该漏洞获取数据库敏感信息,深入利用可控制整个web服务器。 …

计算机图形学:直线生成算法—DDA

DDA&#xff08;Digital Differential Analyzer&#xff0c;数字差分分析器&#xff09;算法是一种基本的直线生成算法&#xff0c;通常用于计算机图形学中。它通过将直线划分为若干个等间隔的小线段&#xff0c;然后在每个小线段中选择一个像素点进行绘制&#xff0c;从而近似…

产品原型图概念

产品原型图概念 产品原型图作用 如下图&#xff1a; 产品原型图的三种分类 线框图 通过【线段色块文字】描述产品页面。优点&#xff1a;制作快速。 缺点&#xff1a;传递信息容易遗漏。 应用&#xff1a;早期方案讨论&#xff0c;需要快速输出的场景&#xff0c;团队配合…

Learn ComputeShader 01 First Computer Shader

使用Unity版本&#xff1a;2019.4.12f1 整体流程&#xff1a; 1添加一个quad object并添加一个无光照材质 2.相机投影模式设置为正交 3.调整quad使其完全显示在相机内 4.创建脚本并且使用计算着色器覆盖quad的纹理 5.创建一个compute shader 前三步完成以后结果应该是这…

网络基础先导

前言&#xff1a;最好在牢固前面几大件&#xff08;编程语言、数据结构、操作系统&#xff09;&#xff0c;并且您有一个服务器的基础上&#xff08;我使用的是腾讯云中配置最低的服务器&#xff09;再来学习本系列的网络知识。 1.网络发展简要 下面就是简单提及一些概念而已&…

二叉树之AVL树

文章目录 1. AVL树的概念&#xff08;logN)1.1背景1.2规则 2.AVL树节点的定义3.AVL树的插入4. AVL树的旋转(重点&#xff09;4.1 新节点插入较高的右子树的右侧&#xff1a;左单璇&#xff1b;4.2 新节点插入较高左子树的左侧&#xff1a;右单璇&#xff1b;4.3&#xff08;双旋…