题解:uoj695 【候选队互测2022】毛估估就行

news/2025/11/2 17:15:45/文章来源:https://www.cnblogs.com/LUlululu1616/p/19185131

题意:给出一个无向无权图,\(q\) 次询问两点距离,但是假设真实距离为 \(d\),输出 \([d-1,d+1]\) 都视为正确。\(n\le 8000,q\le 10^6,m\le n^2\)

做法:

正常的最短路肯定是没法做,做出来就得图灵奖了。注意到输出 \(|ans-d|\le 1\) 都可以,我们考虑去找一些关键点出来对整个图跑 bfs,假设 \((x,y)\) 的最短路径经过关键点 \(u\) 或者 \(u\) 的邻域,那么就会有 \(dis(x,u)+dis(y,u)-2\le dis(x,y)\le dis(x,u)+dis(y,u)\)。直接输出 \(dis(x,u)+dis(y,u)-1\) 就可以保证是对的。询问时不太方便去找 \(u\),但是我们发现对所有的关键点取 \(\min\) 肯定是没问题的,不相邻的肯定差的更多,这样输出就可以了。

但是这样显然不够快,还是 \(O(n)\) 个关键点和 \(O(n^2)\) 的 bfs 合起来是 \(n^3\) 的。我们考虑,当我们拉出来一个关键点后,我们就直接把他和他的邻域全删了,不用在后面的 bfs 中跑。这样并没有时间复杂度保证,但是如果我们换成优先选度数更大的点就有保证了,可以证明是 \(O(n^2)\) 的,接下来我们说明一下这个事情。

假设我们做到第 \(i\) 个关键点的时候剩下 \(m_i\) 条边,那么这个关键点目前的度数一定 \(\ge \frac{2m_i}{n}\),也就是我们会同时删除的点的个数。那么我们会有:

\[\sum\frac{2m_i}n\le \sum deg_{p_i} + 1=n \]

第二个等号的原因是因为所有的点和其邻域的点只会被删一次。

那么我们总共 bfs 的复杂度就是 \(O(\sum m_i) = n^2\)

这样我们可以做到预处理 \(O(n^2)\),询问 \(O(nq)\)

发现这样预处理和询问非常不协调,考虑平衡一下,我们不拉出来 \(n\) 个关键点,而是选前 \(B\) 个。对于剩下没删掉的点就直接暴力跑出两点距离,输出就直接对暴力的和有关键点的取 \(\min\) 即可,询问复杂度 \(O(qB)\)

考虑预处理,首先前面的 bfs 部分肯定还是不大于 \(O(n^2)\) 的复杂度,不用管,主要是后面的复杂度。我们注意到,此时每个点的度数最多为 \(\frac{n}B\),因为如果有多的,那么前面每轮至少删掉 \(\frac{n}B\) 个就删空了,这样总边数就是 \(O(\frac{n^2}{B})\) 的,暴力 bfs 复杂度为 \(O(\frac{n^3}{B})\)

\(B = \sqrt{n^3q}\) 即可,复杂度 \(O(n^{1.5}q^{0.5})\)

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 8005;
int deg[maxn], n, q;
vector<int> e[maxn];
int get_val(char c) {return (isdigit(c) ? c - '0' : c - 'A' + 10);
}
void del(int x) {deg[x] = -1;for (vector<int>::iterator it = e[x].begin(); it != e[x].end(); it++)if(deg[*it] != -1)deg[*it]--;
}
int dis[maxn][maxn];
void bfs(int s) {queue<int> q;dis[s][s] = 0;q.push(s);while(!q.empty()) {int u = q.front(); q.pop();for (vector<int>::iterator it = e[u].begin(); it != e[u].end(); it++) {int v = *it;if(deg[v] != -1 && dis[s][v] > dis[s][u] + 1) {dis[s][v] = dis[s][u] + 1;q.push(v);}}}
}
int p[maxn];
int main() {ios::sync_with_stdio(false);cin >> n >> q;for (int i = 2; i <= n; i++) {string s; cin >> s;for (int j = 1; j < i; j++) {int t = get_val(s[(j - 1) / 4]);if((t >> ((j - 1) % 4)) & 1)e[i].push_back(j), e[j].push_back(i), deg[i]++, deg[j]++;}}memset(dis, 0x3f, sizeof(dis));int B = 100;for (int i = 1; i <= B; i++) {int pos = 0;for (int j = 1; j <= n; j++)if(deg[j] > deg[pos])pos = j;if(pos == 0)break;p[i] = pos;bfs(pos);del(pos);for (vector<int>::iterator it = e[pos].begin(); it != e[pos].end(); it++)if(deg[*it] != -1)del(*it);}for (int i = 1; i <= n; i++) {if(deg[i] == -1)continue;vector<int> res;for (int j = 0; j < e[i].size(); j++)if(deg[e[i][j]] != -1)res.push_back(e[i][j]);swap(res, e[i]);}for (int i = 1; i <= n; i++) {if(deg[i] != -1)bfs(i);}while(q--) {int x, y; cin >> x >> y;int ans = dis[x][y];for (int i = 1; i <= B; i++)if(p[i])ans = min(ans, dis[p[i]][x] + dis[p[i]][y] - 1);cout << ans << '\n';}return 0;
}

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

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

相关文章

@ 和 禁止转义字符串

string str = ""; \r 表示转义字符,如果字符串真的要输入\,需要\表示非转义,如果要输入 \r,应当输入 \\r。 "也需要转义, "" @ 禁止\转义,但是双引号仍旧需要保持转义 """…

11.2 —— (VP)2022icpc南京

日常被打爆,赛时3题,铜牌题被卡 \(O(n\log n\log A)\) 一直疯狂 \(TLE\),赛后发现自己的思路跟正解完全背道而驰。 \(I\) 纯签到。 \(G\):无解情况的判断特别简单,将所有的 \(0\) 看作 \(1\),然后判断前缀和的每…

第二次软件工程作业

https://gitee.com/UUDI/second-software-engineering

Edge---浏览器优化配置

Edge浏览器这款自带的浏览器,使用体验还是可以的。但是内存占用较高,而且关闭Edge浏览器,依然占内存使用。 比如:我打开电脑,都没有使用Edge浏览器,但是依然会占内存:

华为Matebook清灰之后扬声器没声音

华为matebook清灰之后没声音,声卡驱动一切正常,耳机ok。又拆开检查排线是不是插稳了,结果发现排线只要不故意去插拔,根本就没法影响。 重启好几次都没啥用。网上检索了几种方案,组合一下发现莫名奇妙就好了。 htt…

string.replace替换null

string.replace替换nullreplace相当于erase;

类和对象-多态project09

多态的基本语法project9 filename01 多态分为两类 静态多态:函数重载和运算符重载属于静态多态,复用函数名 动态多态:派生类和虚函数实现运行时多态 静态多态和动态多态区别 静态多态的函数地址早绑定-编译阶段确定…

Pointnet++论文学习

背景 在PointNet中并没有局部特征的概念,要么是对单个物体进行处理获取单个特征,要么是进行整体最大池化获取全局特征,丢失了很多局部信息。也是因此在进行分割物体时效果显得一般,Pointnet++则优化了这个问题。 方…

C++的值类型(左值,右值,亡值,泛左值,纯右值)

C++的值类别C++的值的类型,基本可以分为左值,亡值,纯右值,泛左值,右值五种类型。 lvalue 平常我们说的左值就是lvalue,左值一般是指,可以在内存中长久存在的值,可以被取地址。一切具有名字的变量,不论类型如何…

CF1730D Prefixes and Suffixes

题意:给出两个字符串\(s1,s2\) 你可以把s1的k个连续前缀与s2的k个连续后缀交换 k任意选取,可以操作无限次 问是否可以将s1与s2变得相等 观察后发现,存在着某个特性,即将某一个字符串翻转之后,s1[i] == s2[i],这…

工具---短视频下载神器

在看微信视频号、小程序、抖音、快手、小红书、酷狗音乐、QQ音乐的时候,可以通过这个软件将其下载。 软件:res-downloader 在github里面下载:https://gitee.com/zhoumath/res-downloader也可以在国内的下载:https:…

使用iptables双重DNAT

使用iptables双重DNAT 一、需求 由于企业内部网络安全问题,往往只开启一个端口供企业外部业务与也企业内部服务器访问。因此需要在企业网关的前端接一个前置机(192.168.0,91),用于供端口映射处理。 整体架构如下,其…

AT ABC290 F Maximum Diameter 题解

Solution组合好题,注意到 \(n\) 个点的边数为 \(n - 1\),总度数为 \(2n - 2\),因此序列 \(a\) 的权值不为 \(0\) 时当且仅当 \(\sum a = 2n - 2\) 且 \(a_i \gt 0\)。 接下来是一个简单的贪心,如果对于给定的序列需…

ABC430

ABC430C. Truck Driver 二分或双指针 固定区间左端点 \(l\),找到区间中至少有 \(A\) 个 a 的最小右端点 \(r_a\),以及区间中至少有 \(B\) 个 \(b\) 的最小右端点 \(r_b\)。显然条件二更紧,所以用 \(r_b-r_a\) 来更…

团队作业1——团队展示选题-大学生健康生活管理与预警系统

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13471这个作业的目标 通…

广告投放名词

直投 广告主通过广告投放平台或者Marketing API 进行广告的直接投放,利用媒体的用户数据能力以及广告模型进行广告的预估和优化。直投广告的优势在于,广告平台累计了大量的用户基础数据以及产品行为数据,得到丰富的…

自定义Linux 备份命令 backup 【from claude.ai Haiku 4.5】

自定义Linux 备份命令 backup 【from claude.ai Haiku 4.5】测试过能用在日常开发和系统维护中,我们经常需要备份文件和文件夹。虽然 cp 和 tar 命令完全可以胜任,但每次都要手动输入冗长的参数确实很麻烦。今天我就…

打造你自己的 Linux 备份命令:快速、高效、易用 【from claude.ai Haiku 4.5】

打造你自己的 Linux 备份命令:快速、高效、易用 【from claude.ai Haiku 4.5】 在日常开发和系统维护中,我们经常需要备份文件和文件夹。虽然 cp 和 tar 命令完全可以胜任,但每次都要手动输入冗长的参数确实很麻烦。…

CVE-2025-12176漏洞分析:未记录的管理账户安全风险

本文详细分析了CVE-2025-12176高危漏洞,该漏洞由于系统创建未记录的管理账户而存在安全风险。影响BLU-IC2和BLU-IC4至1.19.5版本,CVSS评分达10.0分,攻击者可远程利用此漏洞获取系统权限。概述 CVE-2025-12176是一个…

信安中级考试备忘

个人在备考的笔记,主要针对案例题Linux iptables 四表五链 私网地址A类 10.0.0.0 ~ 10.255.255.255B类 172.16.0.0 ~ 172.31.255.255C类 192.168.0.0 ~ 192.168.255.255ASCII 码记忆 A(65) a(97) 0(48) 空格(32) NUL…