DS图应用--最短路径

news2024/11/24 17:34:28

Description

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

Input

第一行输入t,表示有t个测试实例

第二行输入n,表示第1个图有n个结点

第三行起,每行输入邻接矩阵的一行,以此类推输入n行

第i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开

第四行输入v0,表示求v0到其他顶点的最短路径距离

以此类推输入下一个示例

Output

每行输出v0到某个顶点的最短距离和最短路径

每行格式:v0编号-其他顶点编号—-[最短路径],具体请参考示范数据

Sample

#0
Input

Copy

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

Copy

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算法求最短距离,还不用记录路径

        tips:本题要记录最短路径所经过的点

以起点 A 通往前一个点 B 的最短路径+前一个点 B 到下一个点 C 的路径与 现有的A通到C的路径距离相比较求一个最短的路劲。(这里可能不是太理解,请往下看)
首先先知道一个算法里面一个重要的东西 dis[] 数组,他的意思是起点到终点的距离
设起点为 0 
dis[0],起点 0 到 0 的最短距离
dis[1],起点 0 到 1 的最短距离
dis[2],起点 0 到 2 的最短距离

这里与开头说的联系;
假设 0 到 2 存在一条路距离为10 ,0 到 1 存在一条路距离为2 ,1到2存在一条路距离为3


dis[0]=0
dis[1]=2

此时 0 到 1 的路径是 0-1
然后最开始以 2 为前一个出发点,那到达  2  的最短距离已知的是不是10,dis[2]=10

此时 0 到 2 的路径是 0-2
然后 1 为中转点到达 2 的时候,到达2的距离是不是 到达 1 的距离+ 1 到 2的距离dis[1]+1->2=5
此时dis[1]+3<dis[2]=10
所以dis[2]更新为dis[2]=dis[1]+3

此时路径我们发现 0-2 走的路径比 0-1-2 走的长,所以我们就更新路径
所以 0 到 2 的最短路径为 0-1-2

路径:

起点 0 到 1,最短路径就是 0-1

起点 0 到 2,最短路径就是 0-1-2
起初我们记录的 0 到 2的路径是 0-2,但是我们发现走 0-1-2这条路更近,所以取而代之 

样例(自己出的样例跑一遍)

tips:这里我们记录start到dis[i]的最短路径是不包括i本身的
例如:A到C的最短路径是A-B-C,那我们记录的就只有A-B

dis[A]=无穷大 dis[B]=无穷大 dis[C]=无穷大,dis[D]=无穷大
本题设置A为起点
图如下:

令dis[]都为无穷大

令起点到自己为0,因为自己到自己距离为0嘛

然后dis[]数组中dis[A]是最小的,且没有被作为中转点走过,所以设A为中转点,然后遍历A可以到达的边。这里可以理解为A-A(中转点)-目标点
A可以到达B,C两点,且A到B,C的距离小于无穷大,所以更新起点A到B,C的最短距离为
dis[B]=2,dis[C]=3

此时A到B的最短路径为A
此时A到C的最短路径为A

✔的意思是这个点已经被作为中转点走过了

然后找未被作为起始点且起点到他的距离最短,找到B,因为dis[B]=2,dis[C]=3,dis[A]=0但是A已经作为中转点走过了。
B可以到达D点,
起初dis[D]=无穷大,意思为A到D的最短距离为无穷
现在D的路径有从B到D,他的距离为起点A到达B的最短距离+BD路径的距离
dis[B]+BD=12<无穷大
所以dis[D]=12

此时A到D的最短路径为A-B

然后继续重复步骤
此时没有被走过的点是C,D.dis[C]=3,dis[D]=12
1.C可以到达B
起点A到C的最短距离+CB为B的新一条路距离>dis[B]的前一个路径,即起点A到B的最短路径
dis[C]+CB=8 > dis[B]=2
所以不用更新dis[B]
2.C可以到达D
起点A到D的最短距离+CD为D的新一条路距离<dis[D]的前一个路径,即起点A到D的最短路径
dis[C]+CD=9 > dis[B]=12
所以需要更新起点A到D的最短距离dis[D]=9

此时A到D的路径 A-B的长度大于走A-C的长度
所以更新D的路径为A-C

tips:更新的方法是我们前面已经保存了A到C的路径(不包括C自己),就是路径A,那我们是不是在路径A里面加入要走的C就可以了,就是A-C

最后以D为中转点走,即A到D的最短路径 出发去别的点,但是已经没有D可以到达的点了,所以就结束了

最后得到起点A到别的点的距离
dis[A]=0
dis[B]=2
dis[C]=3
dis[D]=9

最后我们start到各点的最短路径是:

B:A
C:A
D:A-C

最后我们输出实际路径的时候输出完路径再输出终点本身就好了

更新路径的写法:

为什么要清除之前的路径呢。

就比如 A-B-C-D要走10m
但是     A-E-F-D要走5m
那你的最短路径是不是从A到C的最短路径+D变成A到E的最短路径+D
那就把A到C的路径删掉,然后换成A到F的最短路径然后+D

tips:本人写法的最短路径是不包括其本身的
所以A到C的最短路径就是A-B,A到F的最短路径是A-E
所以A到D更新前的路径是A-B-C
更新后的是A到F的最短路径A-E加上F,就是A-E-F

enmmm,意思是到end之前最短路径所经过的点,就是不包括end。
那我求end的最短路径是不是end-1之前最短路径所经过的点加end-1这个点

具体代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int t, n, start;
const int maxn = 2e3 + 10;
int dp[maxn][maxn];//建立的邻接矩阵数组
vector<int>p[maxn];///二维动态数组,记录p[i],起点start到i所需要经过的路径
int vis[maxn];///判断这个点是否有被中转过
int dis[maxn];///dis[i],表示起点start到终点i的最小距离
void irit()
{
    for (int i = 0; i < n; i++)
    {
        vis[i] = 0;///初始化都没有被作为中转点过
        dis[i] = 0x3f3f3f;///初始化全都是无穷大,start到i的最短距离为无穷大
    }
}
void dijkstra()
{
    dis[start] = 0;///start到start自己的最短距离是0
    for (int i = 0; i < n; i++)///  总共需要n个中转点,次数也是n就够了
    {
        int minm = 0x3f3f3f, pre = 0;///
        for (int j = 0; j < n; j++)///遍历所有dis[],找最小距离的点且没有被作为中转点走过的点
        {
            //vis[k]=0即没有被作为中转点,dis[k]即比较dis距离找距离最小的点
            if (!vis[j] && dis[j] < minm)
            {
                minm = dis[j];//更新最短距离
                pre = j;//找距离最小的点
            }
        }
        vis[pre] = 1;///将这个点设置为已经被中转过了
        for (int j = 0; j < n; j++)///找这个中转点可以到达的k点,如果起点到K的距离小于通过中转点到K的距离就不用更新
        {
            ///如果起点到K的距离大于通过中转点到K的距离就需要更新
            ///dp[j][k],j到k是否存在边
       
            if (dp[pre][j] != 0 && dis[j] > dis[pre] + dp[pre][j])
            {
                dis[j] = dis[pre] + dp[pre][j];
                int len = p[pre].size();
                p[j].clear();///把到j的前一个路径清除
                for (int k = 0; k < len; k++)///将start到pre的路径复制下来
                {
                    p[j].push_back(p[pre][k]);
                }
                p[j].push_back(pre);///然后加入pre点
            }

            ///这么干的原因是,上一条路径的长度走的比经过pre中转的点长
            ///那我们就走pre走过的点作为路径,不是比前一条路更短吗
        }
    }
}
int main()
{
    cin >> t;
    while (t--)
    {
        cin >> n;
        irit();
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                cin >> dp[i][j];//构建邻接矩阵
            }
        }
        cin >> start;///输入起点
        dijkstra();
        for (int i = 0; i < n; i++)
        {
            if (i == start)
                continue;
            cout << start << "-" << i << "-" << dis[i] << "----";
            cout << "[";
            int len = p[i].size();
            for (int j = 0; j < len; j++)///输出到j所走过最短路径的点,这个点是不包括他自身的
            {
                cout << p[i][j] << " ";
            }
            cout << i << " ]" << endl;///输出j自身
        }
    }
    return 0;
}


就写到这吧,跟我的追星dijkstra追星还是不说一模一样但也十有八九
原理其实是一样的,但是重要的是掌握我的路径数组的意思,是不包括最后终点自身的

幸苦大家看这么多字了!

夜深了,晚安各位!!!!( ̄o ̄) . z Z

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

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

相关文章

Apollo新版本Beta技术沙龙

有幸参加Apollo开发者社区于12月2日举办的Apollo新版本(8.0)的技术沙龙会&#xff0c;地址在首钢园百度Apollo Park。由于去的比较早&#xff0c;先参观了一下这面的一些产品&#xff0c;还有专门的讲解&#xff0c;主要讲了一下百度无人驾驶的发展历程和历代产品。我对下面几个…

第3章 接入网

文章目录 3.1.1 接入网的定义与接口3.1.2 接入网的功能结构 3.1 接入网概述 3.1.1 接入网的定义与接口 电信网按网络功能分&#xff0c;分为&#xff1a;接入网、交换网和传输网。交换网和传输网合在一起称为核心网。 接入网&#xff08;Access Network&#xff0c;AN&am…

在AWS Lambda上部署标准FFmpeg工具——Docker方案

大纲 1 确定Lambda运行时环境1.1 Lambda系统、镜像、内核版本1.2 运行时1.2.1 Python1.2.2 Java 2 启动EC23 编写调用FFmpeg的代码4 生成docker镜像4.1 安装和启动Docker服务4.2 编写Dockerfile脚本4.3 生成镜像 5 推送镜像5.1 创建存储库5.2 给EC2赋予角色5.2.1 创建策略5.2.2…

[足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-3线性化Linearization

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-数学基础Ch0-3线性化Linearization 1. 线性系统 Linear System 与 叠加原理 Superposition2. 线性化&#xff1a;Taylor Series3. Summary 1. 线性系统 Linear System 与 叠加原理 Superposition…

Linux基础命令(测试相关)

软件测试相关linux基础命令笔记 操作系统 常见Linux&#xff1a; Redhat系列&#xff1a;RHSL、Centos、FedoraDebian系列&#xff1a;Debian、Ubuntu以上操作系统都是在原生Linux系统上&#xff0c;增加了一些软件或功能。linux的文件及路径特点 Linux没有盘符的概念&#xf…

LeetCode-478. 在圆内随机生成点【几何 数学 拒绝采样 随机化】

LeetCode-478. 在圆内随机生成点【几何 数学 拒绝采样 随机化】 题目描述&#xff1a;解题思路一&#xff1a;一个最简单的方法就是在一个正方形内生成随机采样的点&#xff0c;然后拒绝不在内切圆中的采样点。解题思路二&#xff1a;具体思想是先生成一个0到r的随机数len&…

css处理 纯英文数据不换行问题 - word-break、word-wrap

问题图 解决 添加 css 样式 word-break: break-all;补充 还有一个 word-wrap 样式&#xff0c;可以看下 参考 &#xff1a; word-wrap: normal 只在允许的断字点换行&#xff08;浏览器保持默认处理&#xff09;。word-wrap: break-word 在长单词或 URL 地址内部进行换行。

智能优化算法应用:基于闪电连接过程算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于闪电连接过程算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于闪电连接过程算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电连接过程算法4.实验参数设定5.算…

Leetcode—205.同构字符串【简单】

2023每日刷题&#xff08;五十&#xff09; Leetcode—205.同构字符串 算法思想 参考自k神思路 实现代码 class Solution { public:unordered_map<char, char> s2t, t2s;bool isIsomorphic(string s, string t) {int n s.size();for(int i 0; i < n; i) {char …

uniapp横向滚动示例

目录 插件市场案例最后 插件市场 地址 案例 地址 最后 感觉文章好的话记得点个心心和关注和收藏&#xff0c;有错的地方麻烦指正一下&#xff0c;如果需要转载,请标明出处&#xff0c;多谢&#xff01;&#xff01;&#xff01;

【Linux服务器Java环境搭建】07 在linux中安装MySql,以及对MySQL的配置与远程连接

【Linux服务器Java环境搭建】01购买云服务器以及在服务器中安装Linux系统 【Linux服务器Java环境搭建】02 通过xftp和xshell远程连接云服务器 【Linux服务器Java环境搭建】03 Git工具安装 【Linux服务器Java环境搭建】04 JDK安装&#xff08;JAVA环境安装&#xff09; 【Linux服…

HashMap相关专题

前置知识&#xff1a;异或运算 异或运算介绍 异或有什么神奇之处&#xff08;应用&#xff09;&#xff1f; &#xff08;1&#xff09;快速比较两个值 &#xff08;2&#xff09;我们可以使用异或来使某些特定的位翻转&#xff0c;因为不管是0或者是1与1做异或将得到原值的相…

ProEasy机器人案例:电池边包胶

如下图所示&#xff0c;对一个电池三边包边&#xff0c;因客户现场有很多规格电池的大小&#xff0c;所以就需要建立动态的工具坐标来实现适配所有种类的电池 程序如下&#xff1a;Ddome程序 function Speed(num) --速度设置 MaxSpdL(2000) --movl最大速度…

OWASP安全练习靶场juice shop-更新中

Juice Shop是用Node.js&#xff0c;Express和Angular编写的。这是第一个 完全用 JavaScript 编写的应用程序&#xff0c;列在 OWASP VWA 目录中。 该应用程序包含大量不同的黑客挑战 用户应该利用底层的困难 漏洞。黑客攻击进度在记分板上跟踪。 找到这个记分牌实际上是&#…

【layui】layui.table表格实现底部固定两行合计行

halo&#xff0c;下伙伴们&#xff0c;今天小编记录个关于layui开发的系统&#xff0c;layui.table表格实现底部固定两行&#xff08;如&#xff1a;本页合计&#xff0c;全部合计&#xff09; 小编查阅layui文档好像只能设置固定一行&#xff0c;所以就利用js添加css样式来修…

协程的概念,协程+遇到IO切换实现单线程提供并发

1、协程是什么&#xff1f; 协程&#xff0c;英文为coroutine&#xff0c;也被称作轻量级线程或者微线程&#xff0c;是一种用户态的轻量级线程。协程的执行不是由系统内核来调度&#xff0c;而是由用户程序自行控制。这意味着协程的切换非常快&#xff0c;几乎只涉及到几个寄…

【无标题】什么是UL9540测试,UL9540:2023版本增加哪些测试项目

什么是UL9540测试&#xff0c;UL9540:2023版本增加哪些测试项目 UL 9540是美国安全实验室&#xff08;Underwriters Laboratories&#xff09;发布的标准&#xff0c;名称为"UL 9540: Energy Storage Systems and Equipment"&#xff0c;翻译为中文为"能量存储…

案例046:基于微信小程序的云上考场

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【解决办法】Pycharm中新添加或者导入项目文件名红色!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、问题描述二、问题原因三、解决办法 一、问题描述 Pycharm的代码中添加新的文件夹&#xff0c;发现文件夹下的文件名是红色的&#xff0c;如下图&#xff1a; …

人、机不同在于变与多

人擅长变&#xff0c;如变模态、变尺度&#xff0c;而机器侧重多&#xff0c;如多模态、多尺度。 人类擅长变化的能力是由于我们的大脑和思维能力的灵活性所决定的。我们可以通过学习和适应&#xff0c;改变我们的态度、行为方式和观点&#xff0c;以适应不同的情境和环境。例如…