DS图应用--最短路径

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于先更新再缓存这种缓存方案设计的思考

这两天正在做公司缓存方面的设计&#xff0c;然后就把自己的思考过程整理一下。 网上对于这块的内容讲解也非常的多&#xff0c;有些说的也都非常的在理&#xff0c;关于缓存一致性的方案也就那么几种&#xff0c;如&#xff1a;先更新、再删&#xff0c;先删、在更新&#xff…

【Polar靶场WEB签到】

题目&#xff1a; <?phperror_reporting(0);$file $_GET[file];if(!isset($file))$file 1;$file str_replace(../, , $file);include_once($file.".php");highlight_file(__FILE__); ?>解答&#xff1a;1、进入index页面&#xff0c;说让你加弟弟&#x…

WordPiece词表的创建

文章目录 一、简单介绍二、步骤流程2.1 预处理2.2 计数2.3 分割2.4 添加subword 三、代码实现 本篇内容主要介绍如何根据提供的文本内容创建 WordPiece vocabulary&#xff0c;代码来自谷歌&#xff1b; 一、简单介绍 wordpiece的目的是&#xff1a;通过考虑单词内部构造&…

算法通关村第十七关-青铜挑战贪心算法思想

大家好我是苏麟 , 今天说说贪心算法 . 贪心思想很难用理论解释&#xff0c;本文我们先通过案例来感受一下贪心是如何解决问题的 大纲 难以理解的贪心算法贪心问题举例分发饼干柠檬水找零分发糖果 难以理解的贪心算法 贪心的思想非常不好解释&#xff0c;而且越使用权威的语言解…

【隐私计算】安全三方计算(3PC)的加法和乘法计算协议

ABY3中采用replicated secret sharing&#xff08;复制秘密分享&#xff09;机制&#xff0c;即2-out-of-3秘密分享&#xff0c;三个参与方的每一方都拥有share中的两份。下面来看一下这样做有什么好处。 2-out-of-3秘密分享 有 x , y x, y x,y两个操作数&#xff0c;先进行秘…

ttkefu在线客服软件新版即将上线——引领客服行业迈向新篇章

在线客服软件已经成为企业与用户之间沟通的重要桥梁。作为领先的客服解决方案提供商&#xff0c;ttkefu即将推出全新版本的在线客服软件&#xff0c;为客服行业注入新的活力。 一、ttkefu新版在线客服软件的主要特点 智能化客户管理&#xff1a;新版软件将采用先进的自然语言…

sd_webui的实用插件,prompt/lama/human matting/...,持续开源更新!!

热烈欢迎大家在git上star&#xff01;&#xff01;&#xff01;冲鸭&#xff01;&#xff01;&#xff01; 1.prompt优化插件 GitHub - leeguandong/sd_webui_beautifulprompt: beautifulprompt extension performs stable diffusion automatic prompt engineering on a bro…

抖音本地生活服务商申请入口在哪里?具体流程是怎样的?

不论是抖音的本地生活业务&#xff0c;还是后来的支付宝、视频号的本地生活业务&#xff0c;因为市场体量足够庞大&#xff0c;市场前景广阔&#xff0c;一直很受各大创业者的追捧。那么&#xff0c;如此火热的本地生活项目&#xff0c;想要申请成为服务商&#xff0c;具体的申…

某60区块链安全之JOP实战二学习记录

区块链安全 文章目录 区块链安全Jump Oriented Programming实战二实验目的掌握对EVM逆向能力实验环境实验工具实验原理实验内容Jump Oriented Programming实战二 实验步骤Jump Oriented Programming实战二 实验目的 学会使用python3的web3模块 学会分析以太坊智能合约中中Jum…

26、卷积 - 实际上是一个特征提取器

矩阵乘法的本质是特征的融合&#xff0c;卷积算法的本质是特征的提取。 回想一下之前所有介绍卷积的时候&#xff0c;描述了一种卷积运算的场景&#xff0c;那就是一个窗口在图片上滑动&#xff0c;窗口中的数值是卷积核的参数&#xff0c;也就是权值。 卷积的计算本质是乘累…

axios使用

Get请求 Post请求 出问题了&#xff1a; 并发请求 全局配置 多个实例如何处理 拦截器 axios在Vue中的模块封装

Install4J安装界面中如何使用脚本找到依赖程序XShell的安装位置

前言 写了一个工具, 使用Install4j打包, 但因为需要用到XShell, 所以希望在安装界面能够提前让用户配置好XShell的安装位置, 所以对Install4j的安装界面需要自定义, 后期在程序中直接过去安装位置就可以正常使用. 调研 和git-bash不一样, 安装版的XShell没有在注册表里存储安…

FL Studio2024破解版本补丁包下载

FL Studio是一款出色的编曲软件&#xff0c;最新版本的FL Studio21新增了四款全新的插件&#xff0c;覆盖了音频设计、延迟、相位器等等。通过软件的不断更新&#xff0c;我们可以享受到更加智能的电子音乐创作工具&#xff0c;目前&#xff0c;FL Studio的正式版已经推出了超过…

产品创新受赞誉,怿星荣获2023未来汽车(电子和软件)创新创业大赛一等奖

2023未来汽车&#xff08;电子和软件&#xff09;创新创业大赛 11月29日&#xff0c;上海临港&#xff0c;由中国汽车工程学会和中国&#xff08;上海&#xff09;自由贸易试验区临港新片区管理委员会联合举办的“2023未来汽车&#xff08;电子和软件&#xff09;创新创业大赛…

NSSCTF 文件上传漏洞题目

目录 [SWPUCTF 2021 新生赛]easyupload1.0 [SWPUCTF 2021 新生赛]easyupload2.0 [SWPUCTF 2021 新生赛]easyupload3.0 [SWPUCTF 2021 新生赛]easyupload1.0 这是一个文件上传漏洞的题目 我们的思路是上传一句话木马&#xff0c;用工具进行连接 先编写一句话木马 将文件后缀…

一位半加法器,一位全加器,四位全加器

我们这里的加法器只考虑一位的情况。 当我们两个一位相加的话&#xff0c;那么就有两个输入&#xff0c;两个输出&#xff0c;两个输入很好理解&#xff0c;就是两个个位上的数字&#xff0c;0或者是1&#xff0c;那么为什么需要有有个输出呢&#xff1f;难道不是输出一个数就…

麒麟linux将图片批量生成PDF的方法

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; wind…

28、卷积 - 卷积的基础公式

本节推导一下卷积的基础公式,还是先上一张卷积运算的示意图图。 我们知道,一张图片有 3 个维度,分别是长、宽、通道。 这三个维度分别用 3 个字母代替,分别是 H(Height, 对应的是长这一维度), W(Width, 对应的是宽这一维度),C(Channel,对应的是通道这一维度)。 对于…

unity学习笔记19

一、角色动画的使用练习 从资源商店导入的动画资源&#xff08;Character Pack: Free Sample&#xff09;中将资源中的角色创建在场景里&#xff0c;现在场景里存在的角色并没有任何动画。 在资源中找到Animations文件夹&#xff0c;在这个文件有很多模型文件&#xff08;.FBX…

PYthon数据分析学前导语

文章目录 1.学习计划1.1 第一阶段&#xff1a;数据分析阶段1.2 第二阶段&#xff1a;可视化阶段1.3 第三阶段&#xff1a;项目实战阶段 2. 相关工具库的安装2.1.Pandas与Numpy的安装2.2 matplotlib, seaborn, Pyecharts的安装 1.学习计划 欢迎开始Python数据分析系列博客的学习…