【数据结构】B : DS图应用--最短路径

B : DS图应用–最短路径

文章目录

  • B : DS图应用--最短路径
    • Description
    • Input
    • Output
    • Sample
        • Input
      • Output
    • 解题思路:
      • 初始化
      • 主循环
      • 心得:
    • AC代码

Description

给出一个图的邻接矩阵,再给出指定顶点v0,求顶点v0到其他顶点的最短路径

Input

第一行输入t,表示有t个测试实例
第二行输入n,表示第1个图有n个结点
第三行起,每行输入邻接矩阵的一行,以此类推输入n行
第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开
第四行输入v0,表示求v0到其他顶点的最短路径距离
以此类推输入下一个示例

Output

每行输出v0到某个顶点的最短距离和最短路径
每行格式:v0编号-其他顶点编号—-[最短路径],具体请参考示范数据

Sample

Input
1
5
0 5 0 7 15
0 0 5 0 0
0 0 0 0 1
0 0 2 0 0
0 0 0 0 0
0

Output

0-1-5----[0 1 ]
0-2-9----[0 3 2 ]
0-3-7----[0 3 ]
0-4-10----[0 3 2 4 ]

解题思路:

首先先要了解图论里面单源最短路径的实现——Dijkstra算法,知道它是怎么一步步算出源点到每一个点的最短距离的,可以参考这个视频【算法】最短路径查找—Dijkstra算法,然后就看代码,对着视频来进行解释:

// Dijkstra算法实现
void Dijkstra(int start)
{memset(dis, 0x3f, sizeof(dis));memset(fixed, 0, sizeof(fixed));last[start] = -1;dis[start] = 0;int minDisNode, minDis;for (int i = 0; i < n; i++){minDis = INF;for (int j = 0; j < n; j++)if (!fixed[j] && dis[j] < minDis)minDisNode = j, minDis = dis[j];fixed[minDisNode] = true;for (int j = 0; j < n; j++){if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])dis[j] = minDis + g[minDisNode][j], last[j] = minDisNode;}}return 0;
}

初始化

memset(dis, 0x3f, sizeof(dis));  // 设置所有节点到源点的初始距离为无穷大
memset(fixed, 0, sizeof(fixed)); // 初始化所有节点为未固定
last[start] = -1;                // 源点的上一个节点设置为-1
dis[start] = 0;                  // 源点到自身的距离设置为0
  • dis[]数组存储从源点到每个节点的当前最短距离。初始时,除了源点到自身的距离为0外,所有其他距离都设置为无穷大。
  • fixed[]数组用于标记节点是否已经找到了从源点出发的最短路径。
  • last[]数组用于记录到达每个节点的最短路径上的前一个节点,对于源点而言,没有前一个节点,所以设置为-1。

主循环

for (int i = 0; i < n; i++)
{minDis = INF;for (int j = 0; j < n; j++)if (!fixed[j] && dis[j] < minDis)minDisNode = j, minDis = dis[j];fixed[minDisNode] = true;for (int j = 0; j < n; j++){if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])dis[j] = minDis + g[minDisNode][j], last[j] = minDisNode;}
}
  • 第一个for循环遍历所有节点,寻找最短路径。
  • 内层的第一个for循环用于找到当前未固定节点中距离源点最近的节点minDisNode
  • fixed[minDisNode] = true;将找到的最短距离节点标记为已固定。
  • 内层的第二个for循环进行“松弛操作”:通过minDisNode更新其他未固定节点的最短距离。如果通过minDisNode到某个节点的距离比当前记录的距离短,则更新该距离
  • 松弛操作:if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])检查是否存在一条从minDisNodej的边,并且通过这条边到达j的距离是否比当前记录的距离短。如果是,更新dis[j]为通过minDisNodej的新距离,并记录last[j]minDisNode

心得:

一开始学这个算法的时候,可能会想到一个环,对于这个环,例如一个三个节点的环,现在节点一是源点,懵的地方就在于我在第一个次循环之后得出节点一到节点二最短,我就把节点二纳入fixed中,我就有疑惑,如果是一个环的话,那我从节点一到节点三再到节点二为什么不是最短。现在项想明白,在循环内层第一个for循环的时候,就已经挑选出最短的了,哪怕节点一到节点二和节点一到节点三的距离相等,节点三到节点二总不可能为负数吧。

明白这个算法的原理之后,后面的输出就很简单了,直接上代码吧。

AC代码

#include <iostream>
#include <vector>
using namespace std;const int INF = 999999; // 定义无穷大常量void printShortestPath(int u, const vector<int>& previousNodes) {if (u == -1)return;printShortestPath(previousNodes[u], previousNodes);cout << u << " ";return;
}void calculateShortestPaths(int start, const vector<vector<int>>& graph, int n) {vector<int> previousNodes(n, -1);vector<int> shortestDistances(n, INF);vector<int> visitedNodes(n, 0);shortestDistances[start] = 0;for (int i = 0; i < n; i++) {int minDistance = INF, nearestNode = -1;for (int j = 0; j < n; j++)if (!visitedNodes[j] && shortestDistances[j] < minDistance){nearestNode = j;minDistance = shortestDistances[j];}visitedNodes[nearestNode] = 1;for (int j = 0; j < n; j++)if (graph[nearestNode][j] != 0 && minDistance + graph[nearestNode][j] < shortestDistances[j]){shortestDistances[j] = minDistance + graph[nearestNode][j];previousNodes[j] = nearestNode;}}for (int i = 0; i < n; i++) {if (i != start) {cout << start << "-" << i << "-" << shortestDistances[i];cout << "----[";printShortestPath(i, previousNodes);cout << "]" << endl;}}return;
}int main() {int t;cin >> t;while (t--) {int n;cin >> n;vector<vector<int>> graph(n, vector<int>(n));for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> graph[i][j];int sourceNode;cin >> sourceNode;calculateShortestPaths(sourceNode, graph, n);}return 0;
}

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

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

相关文章

SkyWalking配置报警推送到企业微信

1、先在企业微信群里创建一个机器人&#xff0c;复制webhook的地址&#xff1a; 2、找到SkyWalking部署位置的alarm-settings.yml文件 编辑&#xff0c;在最后面加上此段配置 &#xff01;&#xff01;&#xff01;一定格式要对&#xff0c;不然一直报警报不出来按照网上指导…

JVM 堆外内存详解

Java 进程内存占用除了JVM 运行时数据区&#xff0c;还有直接内存&#xff08;Direct Memory&#xff09;区域及 JVM 程序自身也会占用内存 直接内存&#xff08;Direct Memory&#xff09;区域&#xff1a;直接内存通过使用Native堆外内存来存储数据&#xff0c;这意味着数据…

大数据平台实践之CDH6.2.1+spark3.3.0+kyuubi-1.6.0

前言&#xff1a;关于kyuubi的原理和功能这里不做详细的介绍&#xff0c;感兴趣的同学可以直通官网&#xff1a;https://kyuubi.readthedocs.io/en/v1.7.1-rc0/index.html 下载软件版本 wget http://distfiles.macports.org/scala2.12/scala-2.12.16.tgz wget https://archi…

pikachu_php反序列化

pikachu_php反序列化 源代码 class S{var $test "pikachu";function __construct(){echo $this->test;} }//O:1:"S":1:{s:4:"test";s:29:"<script>alert(xss)</script>";} $html; if(isset($_POST[o])){$s $_POST[…

基于python人脸性别年龄检测系统-深度学习项目

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介技术组成1. OpenCV2. Dlib3. TensorFlow 和 Keras 功能流程 二、功能三、系统四. 总结 一项目简介 # Python 人脸性别年龄检测系统介绍 简介 该系统基…

用idea搭建一个spring cloud微服务项目

以下是使用 IntelliJ IDEA 搭建 Spring Cloud 微服务项目的步骤&#xff1a; 创建一个新的 Maven 项目。 在 pom.xml 文件中添加以下依赖&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-…

Android studio 迁移之后打开没反应

把Android studio由d盘迁移到c盘&#xff0c;点击没反应&#xff1b; 需要把C:\Users\xxxx\AppData\Roaming\Google\AndroidStudio2022.3 目录下的studio64.exe.vmoptions 修改为C:&#xff0c;删除该文件会导致无法安装app。 里面配置了一个

SpringMVC问题

文章目录 SpringMVC运行流程MVC的概念与请求在MVC中的执行路径&#xff0c;ResponsBody注解的用途SpringMVC启动流程 SpringMVC运行流程 • 客户端&#xff08;浏览器&#xff09;发送请求&#xff0c;直接请求到 DispatcherServlet 。 • DispatcherServlet 根据请求信息调用 …

SpringBoot问题

文章目录 Springboot特性 Springboot特性 自动装配&#xff1a;提供自动配置的“starter”项目对象模型&#xff08;POMS&#xff09;以简化Maven配置。比如使用 MongoDB 时&#xff0c;只需加入 MongoDB 的 Starter 包&#xff0c;然后配置 的连接信息&#xff0c;就可以直接使…

【React-Router】路由导航

1. 概念 路由系统中的多个路由之间需要进行路由跳转&#xff0c;并且在跳转的同时有可能需要传递参数进行通信。 2. 声明式导航 // /page/Login/index.jsimport { Link } from react-router-dom const Login () > {return <div>登录页{/* 解析成 a 链接 */}<Li…

php获取表单以POST方式或GET方式提交的值

在php中存在两个全局变量&#xff08;数组&#xff09;&#xff0c;其中$_GET数组用来记录表单通过GET方式提交的数据&#xff0c;$_POST数组用来记录表单通过POST方式提交的数据。 一、php获取GET方式提交的值 在php中通过以下代码来获取&#xff1a; $_GET[name] //nam…

Windows平台如何实现RTSP流二次编码并添加动态水印后推送RTMP或轻量级RTSP服务

技术背景 我们在对接RTSP播放器相关的技术诉求的时候&#xff0c;遇到这样的需求&#xff0c;客户做特种设备巡检的&#xff0c;需要把摄像头拍到的RTSP流拉下来&#xff0c;然后添加动态水印后&#xff0c;再生成新的RTSP URL&#xff0c;供平台调用。真个流程需要延迟尽可能…

Anthropic LLM论文阅读笔记

研究时间&#xff1a;与Instrcut GPT同期的工作&#xff0c;虽然其比ChatGPT发布更晚&#xff0c;但是其实完成的时间比ChatGPT更早。与ChatGPT的应用区别&#xff1a;该模型比ChatGPT回答我不知道的概率更高。将强化学习用于大语言模型&#xff08;RLHF&#xff09;&#xff1…

6.基于蜻蜓优化算法 (DA)优化的VMD参数(DA-VMD)

代码原理 基于蜻蜓优化算法 (Dragonfly Algorithm, DA) 优化的 VMD 参数&#xff08;DA-VMD&#xff09;是指使用蜻蜓优化算法对 VMD 方法中的参数进行自动调优和优化。 VMD&#xff08;Variational Mode Decomposition&#xff09;是一种信号分解方法&#xff0c;用于将复杂…

【数据结构】链表中二级指针的应用

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 (注:为方便演示本篇使用的x86系统,因此指针的大小为4个字节) 目录 &#x1f4cc;形参的改变不影响实参! 1.调用函数更改整型时传值调用与传址调用的区别 &#x1f38f;传值…

微服务学习|初识Docker、使用Docker、自定义镜像、DockerCompose、Docker镜像仓库

初识Docker 项目部署的问题 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题 依赖关系复杂&#xff0c;容易出现兼容性问题 开发、测试、生产环境有差异 Docker如何解决依赖的兼容问题的? 将应用的Libs (函数库)、Deps (依赖)配置与应用…

线性回归的正则方法:岭回归和Lasso

线性回归的正则方法包括岭回归&#xff08;Ridge Regression&#xff09;和Lasso回归&#xff08;Least Absolute Shrinkage and Selection Operator Regression&#xff09;。这两种方法都是为了解决线性回归中可能存在的过拟合问题而提出的。 选择使用岭回归还是Lasso回归通常…

使用 goland 开发 golang 项目环境配置

方式1&#xff1a;使用 GOPATH 和 GOROOT 在 goland 中打开&#xff1a;Settings - Go&#xff0c;会看到 GOROOT、GOPATH&#xff0c;其相关解释与配置如下&#xff1a; GOROOT&#xff1a;对应 go 的安装路径&#xff0c;例如&#xff1a;D:\go\binGOPATH&#xff1a;是我们…

JavaScript中的事件循环 为什么是微任务先运行

无意中看到这个问题&#xff0c;以下是个人的看法 1、性能和响应性&#xff1a; 微任务通常比宏任务执行得更快&#xff0c;因为微任务通常涉及更少的工作量。将微任务放在宏任务之前可以尽早执行那些需要快速响应的任务&#xff0c;提高系统的响应性能。 2、Promise 的异步特…

3d标签云实现过程(tagcloud.js)同步原生和 vue

写在前面 本来是没有准备写这个知识点&#xff0c;但是下载这个 js 的时候发现很多都是要钱或者是积分的&#xff0c;我就不明白了一个开源了这么久的 js 怎么还有人拿来挣钱的&#xff0c;同时还有一些只有原生 html 的例子&#xff0c;但是现在都是 框架主导的一些项目&#…