第十三届蓝桥杯C++B组国赛H题——机房 (AC)

news2024/12/23 23:29:58

目录

  • 1.机房
    • 1.问题描述
    • 2.输入格式
    • 3.输出格式
    • 4.样例输入
    • 5.样例说明
    • 6.数据范围
    • 7.原题链接
  • 2.解题思路
  • 3.Ac_code
    • tarjan
    • 倍增LCA

1.机房

1.问题描述

这天, 小明在机房学习。

他发现机房里一共有 n n n 台电脑, 编号为 1 到 n n n, 电脑和电脑之间有网线连 接, 一共有 n − 1 n-1 n1 根网线将 n n n 台电脑连接起来使得任意两台电脑都直接或者间 接地相连。

小明发现每台电脑转发、发送或者接受信息需要的时间取决于这台电脑和 多少台电脑直接相连, 而信息在网线中的传播时间可以忽略。比如如果某台电脑 用网线直接连接了另外 d d d 台电脑, 那么任何经过这台电脑的信息都会延迟 d d d 单 位时间 (发送方和接收方也会产生这样的延迟, 当然如果发送方和接收方都是 同一台电脑就只会产生一次延迟)。

小明一共产生了 m m m 个疑问: 如果电脑 u i u_{i} ui 向电脑 v i v_{i} vi 发送信息, 那么信息从 u i u_{i} ui 传到 v i v_{i} vi 的最短时间是多少?

2.输入格式

输入共 n + m n+m n+m 行, 第一行为两个正整数 n , m n,m n,m

后面 n − 1 n−1 n1 行, 每行两个正整数 x , y x, y x,y 表示编号为 x x x y y y 的两台电脑用网线 直接相连。

后面 m m m 行, 每行两个正整数 u i , v i u_{i}, v_{i} ui,vi表示小明的第 i i i 个疑问。

3.输出格式

输出共 m m m 行, 第 i i i 行一个正整数表示小明第 i i i 个疑问的答案。

4.样例输入

4 3
1 2
1 3
2 4
2 3
3 4
3 3

5.样例说明

这四台电脑各自的延迟分别为 2,2,1,1。

对于第一个询问, 从 2 到 3 需要经过 2,1,3, 所以时间和为 2+2+1=5 。

对于第二个询问, 从 3 到 4 需要经过 3,1,2,4, 所以时间和为 1+2+2+1=6。

对于第三个询问, 从 3 到 3 只会产生一次延迟, 所以时间为 1 。

6.数据范围

n , m ≤ 100000 n,m≤100000 n,m100000

7.原题链接

机房

2.解题思路

还是一道比较明显的求LCA(最近公共祖先)模型的题目,我们可以使用多种方法来解决该问题,这里我们使用更好写的离线的tarjan算法来解决该问题 (已补充倍增做法)。

除去tarjan算法必用的基础数组,我们还有一个数组d[],d[i]记录的是每个点的出度,也就是它的延迟时间,以及数组w[],w[i]的含义是点i到根节点的延迟时间。在通过dfs求出每个点iw[i]以后,在tarjan中我们该如何求出两点的延迟时间呢?

我们设点ij的延迟时间为 f ( i , j ) f(i,j) f(i,j),当我们求得ij的最近公共祖先为anc,我们首先让 f ( i , j ) = w [ i ] + w [ j ] f(i,j)=w[i]+w[j] f(i,j)=w[i]+w[j],但很明显,我们多加了两遍 w [ a n c ] w[anc] w[anc],所以我们需要减去两倍的 w [ a n c ] w[anc] w[anc],但延迟时间还包括经过anc的时间,所以还得加上一个 d [ a n c ] d[anc] d[anc]此处请结合w[]d[]的含义理解。
最后能得出式子: f ( i , j ) = w [ i ] + w [ h ] − w [ a n c ] ∗ 2 + d [ a n c ] f(i,j)=w[i]+w[h]-w[anc]*2+d[anc] f(i,j)=w[i]+w[h]w[anc]2+d[anc]在这里插入图片描述

 假设图中当求DE的延迟时间,根据数组定义我们可知 w [ D ] w[D] w[D] [ A , B , C , D ] [A,B,C,D] [A,B,C,D]四点的延迟时间之和。 w [ E ] w[E] w[E] [ E , B , A ] [E,B,A] [E,B,A]三点延迟之和。从DE点所求应该是 [ D , C , B , E ] [D,C,B,E] [D,C,B,E]四点之和。DE的最近公共祖先为B,可以看出对于从B点开始一直到根节点这一段我们是不需要的,也就是 w [ B ] w[B] w[B]被多加了两遍,所以我们应该减去 w [ B ] ∗ 2 w[B]*2 w[B]2。但最后答案 B B B点本身是应该计算进来的,所以我们单独加进来。其中 l c a ( D , E ) lca(D,E) lca(D,E)即为 B B B,可得式子:
f ( d , e ) = w [ D ] + W [ E ] − w [ l c a ( D , E ) ] ∗ 2 + d [ l c a ( D , E ) ] f(d,e)=w[D]+W[E]-w[lca(D,E)]*2+d[lca(D,E)] f(d,e)=w[D]+W[E]w[lca(D,E)]2+d[lca(D,E)]

我们利用这个式子在tarjan函数中就能得出每个询问的答案,当然对于起始和结束都在同一个节点的情况下,它的答案就是当前节点的出度,我们可以进行特判一下。输入输出较多,建议使用scanfprintf进行输入输出。

时间复杂度:dfs:每个点遍历一次,复杂度级别 O ( n ) O(n) O(n),tarjan算法复杂度接近 O ( n + m ) O(n+m) O(n+m)

3.Ac_code

tarjan

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=100010;

unordered_map<int,vector<int>> gra;
int n,m;
//单个点的出度
int d[N];
//记录点i到根节点的延迟
int w[N];
//并查集数组
int q[N];
//记录答案
int res[N];
int st[N];
//存下查询
vector<PII>	query[N];
//并查集查询
int find(int x){
	if(x!=q[x]) q[x]=find(q[x]);
	return q[x];
}

void dfs(int u,int fa)
{
	w[u]+=d[u];
	for(auto g:gra[u]){
		if(g==fa) continue;
		w[g]+=w[u];
		dfs(g,u);
	}
}

void tarjan(int u)
{
	st[u]=1;
	for(auto j:gra[u]){
		if(!st[j])
		{
			tarjan(j);
			q[j]=u;
		}
	}
	for(auto item: query[u]){
		int y=item.first,id=item.second;
		if(st[y]==2){
			int anc=find(y);
			res[id]=w[y]+w[u]-w[anc]*2+d[anc];
		}
	}
	st[u]=2;
}
int main() 
{
	cin>>n>>m;
	for(int i=0;i<n-1;++i){
		int a,b;
		scanf("%d%d",&a,&b);
		gra[a].push_back(b);
		gra[b].push_back(a);
		d[a]++,d[b]++;
	}
	for(int i=0;i<m;++i){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a!=b){
			query[a].push_back({b,i});
			query[b].push_back({a,i});
		}else{
			res[i]=d[a];
		}
	}
	dfs(1,-1);
	for(int i=1;i<=n;++i) q[i]=i;
	tarjan(1);
	for(int i=0;i<m;++i) printf("%d\n",res[i]);
    return 0;
}

倍增LCA

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int N = 200010;

std::vector<int> e[N];
int n, m;
int depth[N], fa[N][30];
int root;
int w[N], d[N];
void bfs(int root)
{
	memset(depth, 0x3f, sizeof depth);
	depth[0] = 0, depth[root] = 1;
	queue<int> q;
	q.push(root);
	while (!q.empty()) {
		auto t = q.front();
		q.pop();
		for (auto j : e[t]) {
			if (depth[j] > depth[t] + 1) {
				depth[j] = depth[t] + 1;
				q.push(j);
				fa[j][0] = t;
				for (int k = 1; k <= 15; k++) {
					fa[j][k] = fa[fa[j][k - 1]][k - 1];
				}
			}
		}
	}
}

int lca(int a, int b) {
	if (depth[a] < depth[b]) swap(a, b);
	for (int k = 20; k >= 0; k--) {
		if (depth[fa[a][k]] >= depth[b]) {
			a = fa[a][k];
		}
	}
	if (a == b) return a;
	for (int k = 20; k >= 0; --k) {
		if (fa[a][k] != fa[b][k]) {
			a = fa[a][k];
			b = fa[b][k];
		}
	}
	return fa[a][0];
}
void dfs(int u, int fa)
{
	w[u] += d[u];
	for (auto g : e[u]) {
		if (g == fa) continue;
		w[g] += w[u];
		dfs(g, u);
	}
}
void solve()
{
	cin >> n >> m;
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		e[a].push_back(b);
		e[b].push_back(a);
		d[a]++, d[b]++;
	}
	dfs(1, -1);
	bfs(1);
	for (int i = 0; i < m; ++i)
	{
		int a, b;
		cin >> a >> b;
		int c = lca(a, b);
		cout << w[a] + w[b] - w[c] * 2 + d[c] << '\n';
	}
}
int main()
{
	solve();
	return 0;
}

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

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

相关文章

【Linux】基本的指令(三)

大家好我是沐曦希&#x1f495; Linux专栏:Linux零基础学习 文章目录1.时间相关的指令2.Cal指令3.find指令:(非常重要)-name4.grep指令5.zip/unzip指令6.写在最后1.时间相关的指令 date显示 date 指定格式显示时间&#xff1a; date %Y:%m:%d date 用法&#xff1a; date [OPT…

基于javaweb的oa办公管理系统(java+layui+ssm+mysql+jsp+html)

基于javaweb的oa办公管理系统(javalayuissmmysqljsphtml) 运行环境 Java≥8、MySQL≥5.7、Tomcat≥8 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基…

迅为iMX6ULL开发板NXP嵌入式ARM核心板Linux系统i.MX6ULL超STM32

核心板参数 尺寸&#xff1a; 38mm*42mm PCB&#xff1a; 6层 CPU&#xff1a; iMX6ULL ARM Cortex-A7架构 单核 iMX6ULL 商业级&#xff1a; 内存&#xff1a;512M 存储&#xff1a;8G EMMC iMX6ULL 工业级&#xff1a; 内存&#xff1a;256M 存储&#xff1a;512M FL…

python正态分布中的normal函数

python正态分布中的normal函数 概念 1、正态分布又名高斯分布&#xff0c;是人们最常用的描述连续型随机变量的概率分布。 在金融学研究中&#xff0c;收益率等变量的分布假定为正态分布或者对数正态分布(取对数后服从正态分布)。因为形状的原因&#xff0c;正态分布曲线也被…

Mysql实战调优拾遗三

Mysql实战调优拾遗三优化小细节&#xff08;续&#xff09;索引监控查询优化查询慢的原因优化数据访问执行过程的优化查询缓存语法解析和预处理查询优化器优化器的优化策略优化器的优化类型关联与排序优化优化特定类型的查询优化count查询优化关联查询优化子查询优化group by 和…

DOS 命令

前提&#xff1a;打开命令行&#xff0c;winr打开窗口输入cmd回车 1、如何操作DOS命令 建议&#xff1a;初学者在虚拟机中完成实验&#xff01;&#xff01;&#xff01; 开始 --- 运行 --- 输入cmd --- 回车&#xff0c;将调出C:\windows\system32\cmd.exe 或者 win R --- 运…

BH1750( GY-302 )光照传感器

文章目录一、产品简介二、IIC通信三、BH1750的使用四、程序源码这里我先简单的介绍一下BH1750光照传感器模块的基本信息(不多废话)&#xff0c;我将着重讲解它的使用部分&#xff0c;相信对于屏幕前的你也是更关心它是怎么使用的&#xff0c;OK&#xff0c;gogogo&#xff01;&…

2019第一届长安杯

检材一 案情简介 在一起电诈案件中&#xff0c;受害者称自己的银行卡被他人冒用&#xff0c;曾收到假冒公安的短信&#xff0c;因为 自己在一个 P2P 网站中理财&#xff0c;假冒公安称该网站已被列外非法网站&#xff0c;要自己到公安备案网站 填写自己的信息&#xff0c;并…

基于javaweb的crm客户关系管理系统(java+springboot+mysql)

基于javaweb的crm客户关系管理系统(javaspringbootmysql) 运行环境 Java≥8、MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基于javawebsp…

云扩研习社 | RPA高级开发技巧(上)

高级元素选择技巧 XPath介绍 XPath是标准的结构化查询语言&#xff0c;内置丰富的语法、高阶函数可以提供非常强大的目标元素特征描述能力。 XPath是一种强大、复杂的查询语言&#xff1b;XPath与编辑器中内置的选择器没有本质区别&#xff0c;均可作为元素特征描述&#xff…

毕业设计 基于51单片机老人防跌倒GSM短信报警系统

基于51单片机无线蓝牙APP控LED灯亮灭亮度设计1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 GSM SIM800A模块电路设计2.2 蜂鸣器报警电路&#xff08;低电平有效&#xff09;设计2.3 ADXL345倾角传感器模块电路设计2.4 DS18B20温度传感器模块电路设计3、部分代码展示…

面试官问我 “A + B” 算法,我懵了

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

逆向学习-UltraEdit安装

一、相关软件安装 1、UltraEdit 1.1、简介 UltraEdit 是当今销量第一且最为强大的一款高性价比的文本编辑器。尽管不是一款开源软件&#xff0c;但多数程序员都使用这款编辑器&#xff0c;支持多种编程语言的语法着色和外挂编译功能。UltraEdit 是理想的文本、HTML 和十六进…

最新|全新风格原创YOLOv7、YOLOv5和YOLOX网络结构解析图

&#x1f4a1;本篇分享一下个人绘制的原创全新风格YOLOv7网络结构图、YOLOv5网络结构图和YOLOX网络结构图 个人感觉搭配还行&#xff0c;看着比较直观&#xff0c;所以开源分享一下。 文章目录YOLOv5 网络结构图(最新 推荐&#x1f525;&#x1f525;&#x1f525;)YOLOv7 网络…

【C++笔试强训】第十三天

&#x1f387;C笔试强训 博客主页&#xff1a;一起去看日落吗分享博主的C刷题日常&#xff0c;大家一起学习博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a;夜色难免微凉&#xff0c;前方必有曙光 &#x1f31e;。 &#x1f4a6;&a…

YOLOv5、v7改进之三十八:引入RepVGG模型结构

前 言&#xff1a;作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列文章&#xff0c;将重点对YOLOv7的如何改进进行详…

基于javaweb的养老院管理系统(java+springboot+thymeleaf+html+js+mysql)

基于javaweb的养老院管理系统(javaspringbootthymeleafhtmljsmysql) 运行环境 Java≥8、MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基于…

synchronized到底锁的是谁、何时生效

一、synchronized锁的几种形式 synchronized修饰普通方法synchronized修饰静态方法synchronized修饰代码块 1、synchronized修饰普通方法 简单示例 public class Test{private String age;private String name;public synchronized void print(String arg1, String arg2) {…

零代码,让业务人员实现应用创造自由

摘要&#xff1a;以汽车营销场景为例&#xff0c;从AppCube零代码和业务大屏入手&#xff0c;帮助开发者更好地理解AppCube低代码和零代码异同点&#xff0c;在实际使用时能更快选取更合适的工具能力&#xff0c;实现应用构建效率最大化。本文分享自华为云社区《DTT第8期直播回…

超级详细的Vue安装与配置教程

Vue web前端三大主流框架之一,是一套用于构建用户界面的渐进式框架,下面这篇文章主要给大家介绍了关于Vue安装与配置教程的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下 − 目录 一、下载和安装Vue二、创建全局安装目录和缓存日志目录三、配置环境变量 1. 环境…