P8906 [USACO22DEC] Breakdown P [最短路]

news/2024/11/8 21:15:12/文章来源:https://www.cnblogs.com/chenwenmo/p/18535931

P8906 [USACO22DEC] Breakdown P

Solution

  • 经典 trick,删边比较难处理,转换成加边,倒着处理。

  • 那我们接下来要考虑,怎么记录状态,以及,每加一次边要如何更新状态。

  • 还是比较套路地,我们可以求出 \(1\) 到某个点 \(i\) 经过 \(k/2\) 条边的最短路,再求出 \(i\)\(n\) 经过 \(k-k/2\) 条边的最短路。根据这种思想,我们可能会思考折半搜索,分治之类的算法来解决这道题。

  • 如果我们要求 \(k/2\),就要求 \(k/4\),然后又要求 \(k/8\)。注意数据范围 \(k\le 8\),这种数据范围可能会成为解题的关键。那么,\(k/2\le 4\)\(k/4\le 2\)\(k/8\le 1\)\(1\) 显然就是边界,就等于两点间的边权。如何求 \(2\) 呢?是不是只需要合并两条边。求 \(4\) 只需要把 \(2\) 的答案合并。这样一来,我们要记录的信息就非常少,不需要去写分治之类的递归程序。

  • 至于怎么合并。我们先考虑 \(1\) 到某一点 \(i\) 的情况,\(i\)\(n\) 同理。我们设 \(f_i\) 表示 \(1\)\(i\) 经过 \(k/2\) 条边的最短路,设 \(g_{i,j}\) 表示 \(i\)\(j\) 只经过两条边的最短路。为啥 \(f\) 只记录终点,\(g\) 要记录起点和终点,因为 \(f\) 显然只有终点才是有用的,\(g\) 的话要记录起点和终点才能合并给 \(f\),不然咋合并?

  • 先大致口胡一遍算法。

    • 如果 \(k/2=4\),那 \(g+g\to f\)
    • 如果 \(k/2=3\),那么 \(g+w\to f\)\(w\) 是边权。
    • 如果 \(k/2=2\),那么 \(g\to f\)
    • 如果 \(k/2=1\),那么 \(w\to f\)
  • 那我们接下来考虑如何更新状态,且是在正确的复杂度内。

  • 先考虑如何更新 \(g\)。假设当前加的是边 \((u\to v)\),那么 \(i\to u\to v\) 这条路径可能被更新 (\(i\) 是任意点),\(O(n)\) 枚举一个 \(i\),路径 \(u\to v\to j\) 也可能被更新,再 \(O(n)\) 枚举一个 \(j\)。更新 \(g\) 的总复杂度 \(O(n)\)

  • 考虑如何更新 \(f\),这里以 \(k/2=4\) 为例。

    • 假设 \(f_i\) 经过的是这样一条边 \(1\to u\to v\to j\to i\)

    • 如果当前加的边是 \(j\to i\),那么只需要 \(O(n)\) 枚举一个 \(v\),然后 \(g_{1,v}+g_{v,i}\to f_i\) 即可。

    • 如果当前加的边是 \(v\to j\),只需要 \(O(n)\) 枚举 \(i\),然后 \(g_{1,v}+g_{v,i}\to f_i\)

    • 如果当前加的边是 \(u\to v\)\(O(n)\) 枚举 \(i\),然后也是 \(g_{1,v}+g_{v,i}\to f_i\)。(欸,怎么写起来都是一样的,不管了qwq)

    • 以上情况的总复杂度都是 \(O(n)\)

    • 那如果当前加入的是 \(1\to u\) 呢?我们肯定要 \(O(n^2)\) 枚举 \(v\)\(i\),但是注意到,起点为 \(1\) 的边只有 \(O(n)\) 条,于是均摊复杂度只有 \(O(n^3)\),还是能过的。

  • 综上,总复杂度 \(O(n^3)\),于是就可以愉快地 coding 了。

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;const int N = 3e2 + 5, M = N * N, inf = 0x3f3f3f3f;int n, m, k, w[N][N], ans[M];void Min(int &a, int b) {return a = min(a, b), void();}struct Edge {int u, v;} e[M];struct Worker {int f[N]; // st(起点) 到 i 的经过 k 条边的最短路int g[N][N]; // i 到 j 经过 2 条边的最短路int w[N][N]; // 边权int st, k;void init(int _st, int _k) {st = _st, k = _k;memset(f, 0x3f, sizeof(f));memset(g, 0x3f, sizeof(g));memset(w, 0x3f, sizeof(w));}void add(int u, int v, int _w) {w[u][v] = _w;if (k == 1) {if (u == st) f[v] = w[u][v];return;}for (int i = 1; i <= n; i++) {Min(g[i][v], w[i][u] + w[u][v]);Min(g[u][i], w[u][v] + w[v][i]);}if (k == 2) {for (int i = 1; i <= n; i++) f[i] = g[st][i];return;}if (k == 3) {if (u == st) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {Min(f[i], g[u][j] + w[j][i]);}}} else {for (int i = 1; i <= n; i++) {Min(f[i], w[st][u] + g[u][i]);Min(f[i], w[st][v] + g[v][i]);// Min(f[u], w[st][i] + g[i][u]); 该情况不会被更新Min(f[v], w[st][i] + g[i][v]);}}}if (k == 4) {if (u == st) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {Min(f[i], g[u][j] + g[j][i]);}}} else {for (int i = 1; i <= n; i++) {Min(f[i], g[st][u] + g[u][i]);Min(f[i], g[st][v] + g[v][i]);// Min(f[u], g[st][i] + g[i][u]); 该情况不会被更新Min(f[v], g[st][i] + g[i][v]);}}}}
}work1, workn;int main() {cin >> n >> k;m = n * n;for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> w[i][j];for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v;int k1 = k / 2, kn = k - k1;work1.init(1, k1), workn.init(n, kn);for (int i = m; i >= 1; i--) {ans[i] = inf;for (int j = 1; j <= n; j++) ans[i] = min(ans[i], work1.f[j] + workn.f[j]);work1.add(e[i].u, e[i].v, w[e[i].u][e[i].v]);workn.add(e[i].v, e[i].u, w[e[i].u][e[i].v]);}for (int i = 1; i <= m; i++) cout << (ans[i] == inf ? -1 : ans[i]) << "\n";return 0;
}```

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

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

相关文章

hive基础知识分享(三)

今天学习hive的最后部分!写在前面 今天继续学习hive部分的知识。 Hive中如何实现行列转换一行变多行 可以对表使用 LATERAL VIEW EXPLODE(),也可以直接使用 EXPLAIN() 函数来处理一行数据。 SELECT name, col1 FROM testarray2 LATERAL VIEW EXPLODE(weight) t1 AS col1;多行…

一文读懂远程控制协议—Remote Control Protocol

RCP是一种轻量级的通信协议,核心理念是将边缘节点控制器中MCU的协议转换功能迁移至区域控制器ZCU甚至中央控制器Central ECU中实现,从而实现针对边缘节点的远程控制,实现网络中软件集中化,边缘节点轻量化。 随着中央计算+区域控制的中央集中式架构广泛应用,10BASE-T…

2024-2025-1 20241305 《计算机基础与程序设计》第七周学习总结

作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计(https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP)这个作业要求在哪里 2024-2025-1计算机基础与程序设计第七周作业这个作业的目标 1、数组与链表2、基于数组和基于链表实现数据结构3、无序表与有序表4、…

OSSFileBrowse:OSS存储桶遍历漏洞利用工具

简介: 由于经常遇到存储桶遍历漏洞,直接访问文件是下载,不方便预览,且甲方要求证明该存储桶的危害,因此该工具应运而生。 使用javafx做图形化,kkFileView做文件预览接口。 使用: 命令行运行: java -Dfile.encoding=UTF-8 -jar OSSFileBrowse-1.0-SNAPSHOT.jar或者直接点…

NetExec:新型内网/域渗透工具

免责声明 仅供安全研究与学习之用,若将工具做其他用途,由使用者承担全部法律及连带责任,作者及发布者不承担任何法律及连带责任。简介: NetExec是一款强大的自动化网络安全评估和漏洞测试工具,作为已停止维护的CrackMapExec(CME)的现代替代品,它已被渗透测试人员和红队成…

2024-2025-1 20241407《计算机基础与程序设计》第七周学习总结

这个作业属于哪个课程 [2024-2025-1 计算机基础与程序设计](https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP)这个作业要求在哪里 2024-2025-1计算机基础与程序设计第七周作业这个作业的目标 学习数组与链表,基于数组和基于链表实现数据结构,无序表与有序表,树,图…

mysql ubuntu 卸载

mysql 卸载 :引用https://developer.aliyun.com/article/1306777 在 Ubuntu 系统中,MySQL 是一种常用的关系型数据库服务器。有时,我们可能需要完全卸载 MySQL 服务器,包括所有配置文件和数据,以便重新安装或切换到其他数据库服务器。本文将详细介绍在 Ubuntu 中如何完全卸…

MySQLMonitor: 黑盒测试Mysql实时监控辅助工具

MySQLMonitor MySQL实时监控工具(代码审计、黑盒测试辅助工具)使用 1.自行打包使用 git clone https://github.com/fupinglee/MySQLMonitorcd MySQLMonitormvn clean package -DskipTests=true打开target下的jar文件即可执行 2.直接下载使用 https://github.com/fupinglee/My…

初始mysql以及创建

mysql是一个客户端服务器结构的程序 mysql的服务器是真正的本体,负责保存和管理数据,数据都是保存在硬盘上 数据库服务器上可以把很多有业务上联系的表放在一起,构成一个逻辑上的数据集合登陆mysql 打开终端输入mysql -u root -p,然后显示这个就说明mysql客户端连接到了服务…

【论文阅读笔记】Transformer——《Attention Is All You Need》

论文地址:https://arxiv.org/pdf/1706.03762 代码地址:https://github.com/huggingface/transformers目录IntroductionBackgroundModel ArchitectureEncoderLN and BNDecoderAttentionMulti-head AttentionFeed-ForwardPostion Encoding IntroductionRNN,LSTM 处理时序信息的…

Trivy : 容器安全利器

在当今数字化时代,容器化技术已经成为软件开发和部署的重要组成部分。然而,随着容器数量的增加,安全问题也日益突出。为了确保容器环境的安全,我们需要一款强大的工具来检测容器中的漏洞。今天,我将为大家介绍一款优秀的容器漏洞扫描工具:Trivy Container Scanner。本文将…

Hive3.1.2搭建文档包含详细步骤及相关截图以及常见问题解决

hive-3.1.2分布式搭建文档 1、下载,上传,解压,配置环境变量# 1、解压(解压到上级目录) tar -zxvf apache-hive-3.1.2-bin.tar.gz -C..# 2、重名名 mv apache-hive-3.1.2-bin hive-3.1.2# 3、配置环境变量 vim /etc/profile# 4、在最后增加配置 export HIVE_HOME=/usr/loca…