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

news2024/9/21 22:54:41

题目描述

牛站

给定一张由 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.coloradmin.cn/o/1680046.html

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

相关文章

【动态规划五】回文串问题

目录 leetcode题目 一、回文子串 二、最长回文子串 三、分割回文串 IV 四、分割回文串 II 五、最长回文子序列 六、让字符串成为回文串的最少插入次数 leetcode题目 一、回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/…

mysql的explain

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

一种请求头引起的跨域问题记录(statusCode = 400/CORS)

问题表象 问题描述 当我们需要在接口的headers中添加一个自定义的变量的时候&#xff0c;前端的处理是直接在拦截器或者是接口配置的地方直接进行写&#xff0c;比如下面的这段比较基础的写法&#xff1a; $http({method: "post",url:constants.backend.SERVER_LOGIN…

Cache基本原理--以TC3xx为例(2)

目录 1.概述 2. Cache映射模式 3.DCache的数据一致性 4.小结 1.概述 上一篇Cache基本原理--以TC3xx为例(1)-CSDN博客&#xff0c;我们聊了Cache基本概念&#xff0c;接下来我们将继续聊Cache映射模式&#xff0c;DCache的数据一致性问题。 2. Cache映射模式 常见的Cache地…

Postman基础功能-前置脚本与接口关联

大家好&#xff0c;今天给大家分享一下关于 Postman 工具中的前置脚本与接口关联的使用&#xff0c;本文中汇大量用到关于变量的知识&#xff0c;前段时间给大家除了一篇文章分享&#xff0c;可以参考&#xff1a; Postman基础功能-变量设置与使用 一、前置脚本 介绍&#xf…

C++笔试强训day23

目录 1.打怪 2.字符串分类 3.城市群数量 1.打怪 链接 模拟题目&#xff0c;按题意进行模拟就行。 #include <iostream> using namespace std; // 简单模拟 int solve() {int h, a, H, A;cin >> h >> a >> H >> A;if (a > H)return -1;int…

bcb6 lib编程

Library 新建 Library 新建Cpp File File1.cpp extern "C" __declspec(dllexport) int add(int a,int b) {return ab;}Build Project->Build Project1 使用 新建项目 Add New Project Unit1.cpp #pragma hdrstop#include "Unit1.h" //---------…

上班族兼职新篇章:10大实战攻略,轻松年赚1-20万

对于众多上班族而言&#xff0c;如何在工作之余赚取额外收入&#xff0c;开启自己的第一份副业&#xff0c;已成为许多人心中的疑问。每个人的才能和兴趣点不尽相同&#xff0c;但都有机会找到适合自己的兼职方式。接下来&#xff0c;就让我们一起探索这10大实战攻略&#xff0…

es 分词器(五)之elasticsearch-analysis-jieba 8.7.0

es 分词器&#xff08;五&#xff09;之elasticsearch-analysis-jieba 8.7.0 今天咱们就来讲一下es jieba 8.7.0 分词器的实现&#xff0c;以及8.x其它版本的实现方式&#xff0c;如果想直接使用es 结巴8.x版本&#xff0c;请直接修改pom文件的elasticsearch.version版本号即可…

不用投稿邮箱,怎样向各大新闻媒体投稿?

身为单位的信息宣传员,我深知肩上责任重大。每个月,完成单位在媒体上投稿发表文章的考核任务,就如同一场无声的赛跑,既要保证速度,更要注重质量。起初,我遵循“前辈们”的老路,一头扎进了邮箱投稿的海洋。但很快,现实给了我一记重拳——邮箱投稿的竞争犹如千军万马过独木桥,稿件…

【MySQL数据库开发设计规范】之SQL使用规范

欢迎点开这篇文章&#xff0c;自我介绍一下哈&#xff0c;本人姑苏老陈 &#xff0c;是一名JAVA开发老兵。 本文收录于 《MySQL数据库开发设计规范》专栏中&#xff0c;该专栏主要分享一些关于MySQL数据库开发设计相关的技术规范文章&#xff0c;定期更新&#xff0c;欢迎关注&…

AnyMP4 Video Converter for Mac/Win - 视频转换的卓越之选

在当今数字化的时代&#xff0c;视频内容无处不在&#xff0c;而拥有一款强大的视频转换器就显得至关重要。AnyMP4 Video Converter for Mac/win 正是这样一款出类拔萃的工具&#xff0c;为您带来高效、便捷的视频转换体验。 这款视频转换器具备令人惊叹的功能。它支持广泛的视…

【数据结构】C++语言实现二叉树的介绍及堆的实现(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

蓝桥杯-外卖店优先级(简单写法)

“饱了么”外卖系统中维护着 N 家外卖店&#xff0c;编号 1∼N。 每家外卖店都有一个优先级&#xff0c;初始时 (0 时刻) 优先级都为 0。 每经过 1 个时间单位&#xff0c;如果外卖店没有订单&#xff0c;则优先级会减少 1&#xff0c;最低减到 0&#xff1b;而如果外卖店有订…

AWS简介

AWS AWS&#xff0c;全称为Amazon Web Services&#xff0c;是亚马逊公司旗下的云计算服务平台&#xff0c;自2006年起向全球用户提供广泛而深入的云计算服务。AWS是全球最全面、应用最广泛的云平台之一&#xff0c;它从全球的数据中心提供超过200项功能齐全的服务&#xff0c…

类和对象的特性

1.检查错误。 代码&#xff1a; #include <iostream>using namespace std;class Time { private:/* data */ public:Time(/* args */);~Time();void set_time(void);void show_time(void);int hour;int minute;int sec; };Time::Time(/* args */) { }Time::~Time() { }T…

打个样为centos安装mysql(下载安装)

文章目录 一、下载二、卸载mariadb三、创建用户和组四、解压并安装mysql五、修改my.cnf六、配置环境七、初始化数据库八、启动mysql服务、改密码配置远程链接九、完成 如果是windows的服务器&#xff0c;请看我另外一个文章&#xff1a; windows下安装mysql教程 一、下载 htt…

rocketmq的存储和检索

messageId是rocketmq自动生成的。

通用人工智能将如何重塑未来

通用人工智能(AGI)是一种人工智能&#xff0c;具有与人类一样的获取知识、应用知识解决问题和理解能力。与专门处理受限任务的狭义人工智能系统不同&#xff0c;AGI寻求发展先进的认知技能&#xff0c;以促进在不同情况下完成复杂任务。AGI是一种人工智能&#xff0c;试图模仿人…

Linux网络编程——HTTP协议的理解与运用

目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道&#xff0c;协议就是一种约定&#xff0c;客户端与服务端统一的用这种约定进行传输数据。我们…