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,一经查实,立即删除!

相关文章

使用 hiredis 客户端库封装一个简单的 Redis 类

目录 思考一下redis编程的整个过程。 我们作为redis客户端。需要跟redis服务器交互。 封装 Redis 的 C 类的过程可以分为以下几个步骤&#xff1a; 一个完成发布订阅功能的 Redis 类 思考一下redis编程的整个过程。 我们作为redis客户端。需要跟redis服务器交互。 那说白了…

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之间的区别主要体现在线程安全、继承关系与实现接…

Mysql 和 PostgreSQL 到底选啥?

当我深入探讨MySQL和PostgreSQL这两个著名的开源数据库时&#xff0c;我们不仅发现它们在功能、性能和用例方面存在明显的差异&#xff0c;同时也能看出它们各自在特定场景下的独特优势。选择哪一个往往取决于项目的具体需求、团队的熟悉度以及未来的扩展计划。 在这篇文章中&…

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…

Vue3: 获取元素DOM的方法

Vue3中获取dom的方法有两种 : ref模板引用和传统方法 1.ref模板引用 模板引用是官方提出的方法&#xff0c;请看下面的例子&#xff1a; <template><canvas ref"solarCanvas" id"solar" width"1300" height"900"></…

K8S 污点和容忍度(Taint,Toleration)

介绍 在 Kubernetes 中&#xff0c;污点&#xff08;Taints&#xff09;和容忍度&#xff08;Tolerations&#xff09;是用于节点调度的一种机制&#xff0c;它们允许你控制哪些 Pod 能够调度到哪些节点上。 污点&#xff08;Taints&#xff09; 污点是节点上的一种属性&…

从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博客 收获 我这一小片自留地&…

os模块学习

【一】文件路径相关的操作 【1】获取当前文件所在的文件夹路径 # os.path.dirname(__file__) ​ import os file_name os.path.dirname(__file__) print(file_name) # H:\pycharm projects\day\模块学习2 【2】获取当前文件所在的文件路径 # os.path.abspath(__fil…

echarts部分属性使用

标题部分 (title): 控制图表的标题显示&#xff0c;包括主标题和副标题。你可以设置标题的文字内容、样式、位置等属性。 图例部分 (legend): 图例是用来标识每个系列的名称的&#xff0c;可以让用户通过点击图例来控制显示/隐藏对应的数据系列。 提示框部分 (tooltip): 当鼠…

Rust基本数据类型-字符串

一、字符串是什么&#xff0c;怎么用 1、字符串是什么 先说明一下&#xff0c;在Rust中&#xff0c;字符是UniCode编码占4个字节&#xff0c;字符串类型的字符是UTF-8编码的&#xff0c;字节大小为1&#xff5e;3。 字符串类型在Rust中&#xff0c;可以分为&Str和String…

【极速前进】20240415-20240421:TR-DPO、压缩与智能的线性关系、模拟伪代码改善算术能力、Many-shot、合成数据综述

一、TR-DPO&#xff1a;更新reference模型能实现更好的对齐 论文地址&#xff1a;https://arxiv.org/pdf/2404.09656.pdf ​ 语言模型对齐的训练目标是&#xff1a; max ⁡ π θ E x ∼ D , y ∼ π θ ( y ∣ x ) [ r ϕ ( x , y ) ] − β D KL [ π θ ( x , y ) ∥ π …

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

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

OSPF面试题收集

第一章:基础理论部分 基础部分面试官主要是问一些简单得原理,口头描述的东西。不会涉及到报文的参数属性等。 OSPF是什么 定义也就是链路状态协议和距离矢量协议的区别区别。 开放式最短路径优先协议 路由是以自己为根,根据数据库计算去往所有树枝节点的最佳路径放进自己…

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;返回 …