每周一算法:恰好经过K条边的最短路

题目描述

牛站

给定一张由 M M M 条边构成的无向图,点的编号为 1 ∼ 1000 1\sim 1000 11000 之间的整数。

求从起点 S S S 到终点 E E E 恰好经过 K K K 条边(可以重复经过)的最短路。

注意: 数据保证一定有解。

输入格式

1 1 1 行:包含四个整数 K , M , S , E K,M,S,E KMSE

2.. M + 1 2..M+1 2..M+1 行:每行包含三个整数,描述一条边的边长以及构成边的两个点的编号。

输出格式

输出一个整数,表示最短路的长度。

样例 #1

样例输入 #1

2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9

样例输出 #1

10

提示

【数据范围】
2 ≤ M ≤ 100 2≤M≤100 2M100,
2 ≤ K ≤ 1 0 6 2≤K≤10^6 2K106

算法思想

倍增 + Floyd 求状态

根据题目描述,求从起点 S S S到终点 E E E恰好经过 K K K条边的最短路。考虑「Floyd」算法中的状态 d [ K , i , j ] d[K,i,j] d[K,i,j]表示经过编号 1 ∼ K 1\sim K 1K的点进行中转、从顶点 i i i j j j的最短距离。本题可以用类似的状态 d [ K , i , j ] d[K,i,j] d[K,i,j]表示为恰好经过 K K K条边,从顶点 i i i j j j的最短距离。

要计算状态 d [ K , i , j ] d[K,i,j] d[K,i,j],很容易想到 d [ K , i , j ] = m i n { d [ K − 1 , i , k ] + g [ k , j ] } d[K,i,j]=min\{d[K-1, i, k]+g[ k, j]\} d[K,i,j]=min{d[K1,i,k]+g[k,j]},枚举一个中转点 k k k,从 K − 1 K-1 K1阶段的状态转移到 K K K。这样做的时间复杂度为 K × n 3 K\times n^3 K×n3,从数据范围来看, 2 ≤ M ≤ 100 , 2 ≤ K ≤ 1 0 6 2≤M≤100,2≤K≤10^6 2M1002K106,显然会TLE。

进一步分析,不妨假设 K = a + b K=a+b K=a+b,那么 d [ K , i , j ] = m i n { d [ a , i , k ] + d [ b , k , j ] } d[K,i,j]=min\{d[a,i,k]+d[b,k,j]\} d[K,i,j]=min{d[a,i,k]+d[b,k,j]},其中 k k k表示从 i i i出发经过恰好 a a a条边到达的顶点, 1 ≤ k ≤ n 1\le k\le n 1kn,如下图所示:
在这里插入图片描述
可以发现从顶点 i i i走到 k k k,和从顶点 k k k走到 j j j,这两个部分是完全独立的,并不相互依赖,所以先求前面、或者先求后面没有任何区别。也就是说,对于路径的组合可以是任意的,结合在一起答案不变,类似于加法结合律。

基于上述分析,可以使用快速幂“倍增”的思想,依次计算出 d [ 1 , i , j ] → d [ 2 , i , j ] → d [ 4 , i , j ] → . . . d[1,i,j]\to d[2,i,j]\to d[4,i,j]\to... d[1,i,j]d[2,i,j]d[4,i,j]...,可以将时间复杂度优化为 O ( l o g K × n 3 ) O(logK\times n^3) O(logK×n3)

离散化点集

除此之外,从给出的数据范围来看,边数 M ≤ 200 M\le200 M200 200 200 200条边最多连接 400 400 400个点,那么就需要对所有点进行离散化,重新编号为 1 ∼ n 1\sim n 1n

代码实现

#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int g[N][N], d[N][N];
int n, m, K, S, E;
map<int, int> idx; //离散化点集
void mul(int c[][N], int a[][N], int b[][N])
{
    static int temp[N][N];
    memset(temp, 0x3f, sizeof temp);
    for(int k = 1; k <= n; k ++)
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j ++)
                temp[i][j] = min(temp[i][j], a[i][k] + b[k][j]);
    memcpy(c, temp, sizeof temp);
}
void qmi()
{
    //初始话状态数组
    memset(d, 0x3f, sizeof d);
    for(int i = 1; i <= n; i ++) d[i][i] = 0;
    
    while(K)
    {
        if(K & 1) mul(d, d, g); // d = d * g
        mul(g, g, g); //g = g * g
        K >>= 1;
    }
}
int main()
{
    cin >> K >> m >> S >> E;
    memset(g, 0x3f, sizeof g); //初始化邻接矩阵
    //离散化起点和终点,重新分配编号
    idx[S] = ++ n; idx[E] = ++ n; 
    S = idx[S], E = idx[E];
    
    for(int i = 0; i < m; i ++)
    {
        int a, b, c;
        cin >> c >> a >> b; //注意输入顺序
        //将点离散化,重新分配编号
        if(!idx.count(a)) idx[a] = ++ n;
        if(!idx.count(b)) idx[b] = ++ n;
        a = idx[a], b = idx[b]; 
        g[a][b] = g[b][a] = min(g[a][b], c);
    }
    
    qmi(); //快速幂,倍增求状态
    
    cout << d[S][E] << endl;
    return 0;
}

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

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

相关文章

维护表空间中的数据文件

目录 向表空间中添加数据文件 从表空间中删除数据文件 删除users表空间中的users02.dbf数据文件 对数据文件的自动扩展设置 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 维护表空间中的数据文件主要包括向表空间中添…

C#【进阶】委托和事件

委托和事件 文章目录 1、委托1、委托概念2、基本语法3、定义自定义委托4、使用自定义委托5、委托变量可以存储多个函数6、系统定义好的委托思考 怪物死亡数据更新 2、事件1、事件概念2、事件的使用3、为什么有事件思考 热水器 3、匿名函数1、匿名函数概念2、基本语法3、使用4、…

电工能混到这份上

最近看到某电工师傅发了一篇帖子&#xff0c;大致内容是他在处理一个简单故障的时候居然花了很长的时间。我们一起来看看他遇到的是什么故障吧! plc 控制的一台设备&#xff0c;行走部分靠 2 个脚踏开关控制&#xff08;内部开关量控制方向&#xff0c;电位器控制速度&#xff…

jspXMl标记语言基础

1.打开命令框进入数据库 打开eclipse创建需要连接的项目 粘贴驱动程序 查看驱动器 使用sql的包 int代表个 conlm代表列名 <%page import"java.sql.ResultSet"%> <%page import"java.sql.Statement"%> <%page import"java.sql.Connect…

fl studio试用版文件保存无法打开??一个方法教你免费打开!

前言 当下&#xff0c;各款编曲软件五花八门&#xff0c;而这其中最有声誉的必为FL Studio莫属 这个软件呢国人习惯叫他水果&#xff0c;拥有强大的录音、编曲、混音等功能&#xff0c;所以广受音乐圈欢迎。如今&#xff0c;大部分水果一旦有编曲所需&#xff0c;一般都要使用…

阿里云 服务之前设置的密钥登陆,关闭了密码登录,现在打开密码登录

通过网页远程链接 切换用户 sudo -i 输入vim /etc/ssh/sshd_config 进入配置文件 找到 将这一项设置为yes 重启系统 systemctl restart sshd.service

std::remove-----std::remove_if

std::remove和std::remove_if 是 C11 标准库中的一个算法函数. std::remove 作用 遍历一遍容器&#xff0c;将容器中所有不是指定元素的元素往前复制。 总之就是一句话&#xff1a; 把不该删除的移动到前面&#xff0c;后面的就是应该删除的。 注意&#xff1a; 1&#…

汇聚荣科技:拼多多上架商品后需要做页面推广吗?

在电商平台上&#xff0c;商品的曝光率和销量往往成正比。那么&#xff0c;当您在拼多多上架了新品&#xff0c;是不是就意味着坐等订单呢?答案显然是否定的。商品一旦上架&#xff0c;接下来需要做的就是通过有效的页面推广来增加商品的可见度&#xff0c;吸引潜在买家的注意…

Golang RPC实现-day02

导航 Golang RPC实现一、客户端异步并发多个请求1、 客户端结构体2、 一个客户端&#xff0c;异步发送多个请求&#xff0c;使用call结构体代表客户端的每次请求3、客户端并发多个请求4、客户端接收请求 Golang RPC实现 day01 我们实现了简单的服务端和客户端。我们简单总结一…

Pencils Protocol Season 2 收官在即,展望Season 3 及其权益

此前 Scroll 生态 LaunchPad &聚合收益平台 Pencils Protocol&#xff08;原 Penpad&#xff09;&#xff0c;推出了首个资产即其生态代币 PDD 的 Launch&#xff0c;Season 2 活动主要是用户通过质押 ETH 代币、组件战队等方式&#xff0c;来获得 Point 奖励&#xff0c;并…

mysql的explain

explain可以用于select&#xff0c;delete&#xff0c;insert&#xff0c;update的statement。 当explain用于statement时&#xff0c;mysql将会给出其优化器&#xff08;optimizer&#xff09;的执行计划。 通过explain字段生成执行计划表。下面来解析这个执行计划表的每一列…

正则表达式和sed

一、正则表达式 主要用来匹配字符串&#xff08;命令结果&#xff0c;文本内容&#xff09;&#xff0c; 通配符匹配文件&#xff08;而且是已存在的文件&#xff09; 基本正则表达式 扩展正则表达式 1.元字符 . 匹配任意单个字符&#xff0c;可以是一个汉字 […

【企业宣传片】拍摄思维提升,专业影视质感核心揭密,一课搞定

课程下载&#xff1a;【企业宣传片】拍摄-课程网盘链接提取码下载.txt资源-CSDN文库 更多资源下载&#xff1a;关注我。 课程介绍 大量案例分析宣传片拍摄的痛点要点 根据案例告诉你解决方案&#xff0c;讲透概念 改变你对企业宣传片的思维层级与认知 归纳总结对比不同案…

基于SSM的婚恋网站的设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的婚恋网站的设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…

MS41908M替代AN41908

产品简述 MS41908M 是一款用于网络摄像机和监控摄像机的镜头 驱动芯片他可完全替代AN41908。 芯片内置光圈控制功能&#xff1b;通过电压驱动方式以及扭矩纹 波修正技术&#xff0c;实现了噪声微步驱动。 主要特点 电压驱动方式&#xff0c;256 微步驱动电路&#xff08;两通道…

多区域OSPF路由配置

一、基础配置 1.搭建实验拓扑图 2.实验编址 具体如何配置可以看这一篇详细的博文&#xff1a;单区域OSPF实验-CSDN博客 3.分别检查六个路由器的配置&#xff1a; 使用命令display ip interface brief R1的配置 其他大家可以调出来&#xff0c;再与实验拓扑图进行比对&#…

机器人非线性系统反馈线性化与解耦

机器人非线性系统的反馈线性化和解耦是控制理论中的两个重要概念&#xff0c;它们分别用于简化系统分析和设计过程&#xff0c;提高控制系统的性能。 首先&#xff0c;反馈线性化是一种将非线性系统转化为线性系统的技术。在机器人控制中&#xff0c;由于机器人本身是一个强耦…

那些年我与c++的叫板(一)--string类自实现

引子&#xff1a;我们学习了c中的string类&#xff0c;那我们能不能像以前数据结构一样自己实现string类呢&#xff1f;以下是cplusplus下的string类&#xff0c;我们参考参考&#xff01; 废话不多说&#xff0c;直接代码实现&#xff1a;&#xff08;注意函数之间的复用&…

【C语言】5.C语言函数(2)

文章目录 7.嵌套调⽤和链式访问7.1 嵌套调⽤7.2 链式访问 8.函数的声明和定义8.1 单个⽂件8.2 多个⽂件8.3 static 和 extern8.3.1 static 修饰局部变量8.3.2 static 修饰全局变量8.3.3 static 修饰函数 7.嵌套调⽤和链式访问 7.1 嵌套调⽤ 嵌套调用就是函数之间的互相调用。…

1、sql server数据库进行sql注入

靶机取自&#xff1a;墨者sql server 1、判断数据库类型 抓包知sql server&#xff0c;所以注入语句跟MySQL有些区别 2、判断注入点 “http://219.153.49.228:42514/new_list.asp?id2 ”&#xff0c;当id2 and 11时显示正确&#xff0c;id2 and 12时页面报错。 3、确定列…