Tree Compass( Codeforces Round 934 (Div. 2) )
Tree Compass( Codeforces Round 934 (Div. 2) )
You are given a tree with n n n vertices numbered 1 , 2 , … , n 1, 2, \ldots, n 1,2,…,n. Initially, all vertices are colored white.
You can perform the following two-step operation:
- Choose a vertex v v v ( 1 ≤ v ≤ n 1 \leq v \leq n 1≤v≤n) and a distance d d d ( 0 ≤ d ≤ n − 1 0 \leq d \leq n-1 0≤d≤n−1).
- For all vertices u u u ( 1 ≤ u ≤ n 1 \leq u \leq n 1≤u≤n) such that dist † ( u , v ) = d \text{dist}^\dagger(u,v)=d dist†(u,v)=d, color u u u black.
Construct a sequence of operations to color all the nodes in the tree black using the minimum possible number of operations. It can be proven that it is always possible to do so using at most n n n operations.
† ^\dagger † dist ( x , y ) \text{dist}(x, y) dist(x,y) denotes the number of edges on the (unique) simple path between vertices x x x and y y y on the tree.
Input
Each test contains multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 200 1 \leq t \leq 200 1≤t≤200) — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 3 1 \le n \le 2 \cdot 10^3 1≤n≤2⋅103) — the number of vertices of the tree.
The following n − 1 n - 1 n−1 lines of each test case describe the edges of the tree. The i i i-th of these lines contains two integers u i u_i ui and v i v_i vi ( 1 ≤ u i , v i ≤ n 1 \le u_i, v_i \le n 1≤ui,vi≤n, u i ≠ v i u_i \neq v_i ui=vi), the indices of the vertices connected by the i i i-th edge.
It is guaranteed that the given edges form a tree.
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 3 2 \cdot 10^3 2⋅103.
Output
For each test case, first output a single integer o p op op ( 1 ≤ o p ≤ n ) (1 \le op \le n) (1≤op≤n), the minimum number of operations needed to color all vertices of the tree black.
Then, output o p op op lines, each containing 2 2 2 integers. The i i i-th line should contain the values of v v v and d d d chosen for the i i i-th operation ( 1 ≤ v ≤ n 1 \le v \le n 1≤v≤n, 0 ≤ d ≤ n − 1 0 \le d \le n - 1 0≤d≤n−1)
You must guarantee that at the end of o p op op operations, all vertices are colored black.
If there are multiple solutions, you may output any one of them.
Example
Input
4121 241 21 31 472 73 26 45 71 66 7
Output
1
1 0
2
1 1
2 1
2
1 1
2 1
3
6 1
7 1
2 1
Note
In the first test case, there is only one possible operation, and performing it gives us a valid answer.
In the second test case, the first operation colors vertex 2 2 2 black, and the second operation colors vertex 1 1 1 black. It can be shown that it is impossible to color both vertices black in one operation, so the minimum number of operations needed is 2 2 2. Another possible solution is to use the 2 2 2 operations: ( u , r ) = ( 1 , 0 ) (u, r) = (1, 0) (u,r)=(1,0) and ( u , r ) = ( 2 , 0 ) (u, r) = (2, 0) (u,r)=(2,0).
In the third test case, the first operation colors vertices 2 2 2, 3 3 3 and 4 4 4 black, and the second operation colors vertex 1 1 1 black. Again, it can be shown that it is impossible to color all vertices black in 1 1 1 operation, so the minimum number of operations needed is 2 2 2.
In the fourth test case, the first operation colors vertices 4 4 4, 1 1 1 and 7 7 7 black, the second operation colors vertices 2 2 2, 5 5 5 and 6 6 6 black while the third operation colors vertices 3 3 3 and 7 7 7 black. Notice that it is allowed to color vertex 7 7 7 black twice.
Thus, each node was marked at least once, with node 7 7 7 marked twice. It can be shown that it is impossible to color all vertices black in fewer than 3 3 3 moves.
题解进一步分析和拓展
这个问题的关键在于树的直径,即树中两个最远节点之间的路径长度。直径的长度和树的染色策略有很大关系。接下来我们详细分析如何利用直径的性质优化我们的染色操作,并提出最优的染色方案。
一、直径链的染色操作
考虑一条长度为 (d) 的链,链上的每个节点都需要染色,操作一次最多能染黑链上的 2 个点。我们从树的直径出发,考虑如何使用最少的操作将所有节点染黑。
1. 直径 (d) 为奇数
-
当直径 (d) 是奇数时,我们可以选择直径的中点 (u),然后进行一系列操作,操作的顺序是从 (u) 出发,染色 (u) 和与其距离为 (0, 1, 2, …, d-1) 的节点。这些操作的形式可以是:
[
(u, 0), (u, 1), (u, 2), …, (u, d-1)
]这样,通过最多 ( \frac{d+1}{2} ) 次操作,所有节点都能被染黑,因为每次操作都会把 2 个点染黑。
2. 直径 (d) 为偶数
-
当直径 (d) 为偶数时,我们面临的挑战是如何通过最少次数的操作,覆盖整棵树的所有节点。这里分为两种情况:
-
当 (d \mod 4 = 0)(即直径长度为 4 的倍数):
我们可以选择直径的中心边 ( (x, y) ),然后交替地进行以下操作:[
(x, 1), (y, 1), (x, 3), (y, 3), …, (x, d/2 - 1), (y, d/2 - 1)
]这样只需要 ( \frac{d}{2} ) 次操作。
-
当 (d \mod 4 = 2)(即直径长度为 2 或 6 的余数为 2):
由于不能完全通过交替操作来染色,我们只能从中心出发,进行如下操作:[
(x, 0), (x, 1), (x, 2), …, (x, d/2)
]这样需要 ( \frac{d}{2} + 1 ) 次操作。
-
二、整体思路
-
找直径:
- 通过两次 DFS 来找到树的直径。第一次 DFS 从任意节点出发,找到最远的节点 (A);第二次 DFS 从 (A) 开始,找到最远的节点 (B),则 (A) 到 (B) 的路径即为树的直径。
-
根据直径的长度选择操作策略:
- 如果直径 (d) 为奇数,从中点出发进行操作。
- 如果直径 (d) 为偶数,分为两种情况:
- 如果 (d \mod 4 = 0),通过中心边交替操作。
- 如果 (d \mod 4 = 2),从中心出发逐渐染色。
-
输出操作结果:
- 输出最少的操作次数和每次操作的具体节点及距离。
三、时间复杂度分析
- DFS 查找直径的时间复杂度是 (O(n)),每次 DFS 都需要遍历整个树的节点和边,最多遍历 (n-1) 条边。
- 操作计算 的时间复杂度是 (O(1)),因为操作次数由直径的长度确定,而直径已经通过 DFS 计算出来。
- 因此,每个测试用例的时间复杂度是 (O(n)),而给定 (T) 个测试用例,所有测试用例的总时间复杂度为 (O(T \cdot n))。题目保证了总节点数 (n) 不超过 2000,所以这是一个高效的解法。
四、代码实现
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int N = 2e3 + 10;int n;
vector<int> g[N];
int fa[N];
int started;
int ended;
int height;
vector<int> rode;void dfs1(int x, int f, int h)
{for (auto it : g[x]){if (it == f){continue;}dfs1(it, x, h + 1);}if (h > height){height = h;started = x;}
}void dfs2(int x, int f, int h)
{fa[x] = f;for (auto it : g[x]){if (it == f){continue;}dfs2(it, x, h + 1);}if (h > height){height = h;ended = x;}
}void cleared()
{for (int i = 0; i <= n; ++i){g[i].clear();fa[i] = 0;}height = 0;rode.clear();
}void solved()
{cin >> n;for (int i = 0; i < n - 1; ++i){int x, y;cin >> x >> y;g[x].push_back(y);g[y].push_back(x);}dfs1(1, 0, 1);// cout << started << endl;height = 0;dfs2(started, 0, 1);int now = ended;while (now != 0){rode.push_back(now);now = fa[now];}// cout << ended << endl;// for (auto it : rode)// {// cout << it << ' ';// }// cout << endl;if (height % 2 == 1){cout << height / 2 + 1 << endl;for (int i = 0; i <= height / 2; ++i){cout << rode[height / 2] << ' ' << i << endl;}}else if (height % 4 == 0){cout << height / 2 << endl;for (int i = 1; i <= height / 2 - 1; i += 2){cout << rode[height / 2 - 1] << ' ' << i << endl;cout << rode[height / 2] << ' ' << i << endl;}}else{cout << height / 2 + 1 << endl;for (int i = 0; i <= height / 2; i++){cout << rode[height / 2 - 1] << ' ' << i << endl;}}cleared();
}signed main()
{BoBoowen;int T = 1;cin >> T;while (T--){solved();}
}
五、总结
- 树的直径是这道题的核心,利用树的直径来优化染色操作,可以大幅减少操作次数。
- 根据直径的长度,决定从中点出发进行染色或者采用交替操作,这样能够保证染色的最优性。
- 时间复杂度为 (O(n)),对于每个测试用例能够在合理时间内求解出最少的染色操作次数。
相关文章:
Tree Compass( Codeforces Round 934 (Div. 2) )
Tree Compass( Codeforces Round 934 (Div. 2) ) You are given a tree with n n n vertices numbered 1 , 2 , … , n 1, 2, \ldots, n 1,2,…,n. Initially, all vertices are colored white. You can perform the following two-step operation: …...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.17 掩码数组:缺失值处理的优雅方案
2.17 掩码数组:缺失值处理的优雅方案 目录 #mermaid-svg-12vjJJbyudPnkYBO {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-12vjJJbyudPnkYBO .error-icon{fill:#552222;}#mermaid-svg-12vjJJbyudPnkYBO…...
PHP 常用函数2025.02
PHP implode() 函数 语法 implode(separator,array) 参数描述separator可选。规定数组元素之间放置的内容。默认是 ""(空字符串)。array必需。要组合为字符串的数组。 技术细节 返回值:返回一个由数组元素组合成的字符串。PHP 版…...

react中如何获取dom元素
实现代码 const inputRef useRef(null) inputRef.current.focus()...

【C++】继承(下)
大家好,我是苏貝,本篇博客带大家了解C的继承(下),如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 5.继承与友元6.继承与静态成员7.复杂的菱形继承及菱形虚拟继承8.继…...
C语言实现字符串排序:从代码到原理深度解析
在编程的世界里,字符串处理是一项基础且重要的技能。今天,我们通过分析一段C语言代码来深入了解如何对字符串进行排序。 一、代码呈现 #include <stdio.h> #include <string.h> int main() { char s[1001]; scanf("%s", s); int…...

Vue3的el-table-column下拉输入实时查询API数据选择的实现方法
由于本人对el-table-column有下拉输入选择的要求,根据网上搜索的资料及本人优化,推出我比较满意的方法,供各位读者参考使用。 效果图 el-table-column写法 <el-table-columnlabel"货品编号"align"center"prop"…...

【数据结构】_链表经典算法OJ:复杂链表的复制
目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接:138. 随机链表的复制 - 力扣(LeetCode) 题目描述: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,…...

Vue 图片引用方式详解:静态资源与动态路径访问
目录 前言1. 引用 public/ 目录2. assets/ 目录3. 远程服务器4. Vue Router 动态访问5. 总结6. 扩展(图片不显示) 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 在 Vue 开发中&#x…...
chatGPT写的网页版贪吃蛇小游戏
chatGPT写的网页版贪吃蛇小游戏 前言网页版贪吃蛇小游戏 前言 之前无聊,让ChatGPT写了一段基于html语言的贪吃蛇小游戏代码 网页版贪吃蛇小游戏 将以下内容复制到记事本,重命名为xxx.html即可打开浏览器游玩 这里是一个使用HTML、CSS和JavaScript编写…...
Python量化交易助手:xtquant的安装与应用
Python量化交易助手:xtquant的安装与应用 技术背景和应用场景 在量化交易领域,Python因其强大的库支持和灵活性成为了许多开发者的首选语言。其中,xtquant 是迅投官方开发的一个Python包,专门用于与miniqmt通信,实现…...

前缀和算法
文章目录 算法总览题目1371.每个元音包含偶数次的最长子字符串 算法总览 题目 1371.每个元音包含偶数次的最长子字符串 1371.每个元音包含偶数次的最长子字符串 参考博主的讲解 思路分析:就是得使用前缀和记录情况,dp[i][j]表示s[0] 到s[i] 中&…...

Qt常用控件 输入类控件
文章目录 1.QLineEdit1.1 常用属性1.2 常用信号1.3 例子1,录入用户信息1.4 例子2,正则验证手机号1.5 例子3,验证输入的密码1.6 例子4,显示密码 2. QTextEdit2.1 常用属性2.2 常用信号2.3 例子1,获取输入框的内容2.4 例…...
《最小阻力之路》关于愿景的理解和思考
一、愿景的形成机制 1. 愿景的三层来源 来源层级形成机制案例潜在偏差风险① 本能冲动层对快感/痛苦的即时反应"想暴富"源于缺钱焦虑易被短期情绪劫持② 社会镜像层内化外界标准(家庭/社会/文化)"必须考研"因家人期待混淆他人需求…...

Ubuntu 22.04系统安装部署Kubernetes v1.29.13集群
Ubuntu 22.04系统安装部署Kubernetes v1.29.13集群 简介Kubernetes 的工作流程概述Kubernetes v1.29.13 版本Ubuntu 22.04 系统安装部署 Kubernetes v1.29.13 集群 1 环境准备1.1 集群IP规划1.2 初始化步骤(各个节点都需执行)1.2.1 主机名与IP地址解析1.…...
虚幻基础17:动画层接口
能帮到你的话,就给个赞吧 😘 文章目录 animation layer interface animation layer interface 动画层接口:动画图表的集。仅有名字。 添加到动画蓝图中,由动画蓝图实现动画图表。...

无人机PX4飞控 | PX4源码添加自定义uORB消息并保存到日志
PX4源码添加自定义uORB消息并保存到日志 0 前言 PX4的内部通信机制主要依赖于uORB(Micro Object Request Broker),这是一种跨进程的通信机制,一种轻量级的中间件,用于在PX4飞控系统的各个模块之间进行高效的数据交换…...

HTMLCSS :下雪了
这段代码创建了一个动态的雪花飘落加载动画,通过 CSS 技术实现了雪花的下落和消失效果,为页面添加了视觉吸引力和动态感。 大家复制代码时,可能会因格式转换出现错乱,导致样式失效。建议先少量复制代码进行测试,若未能…...
如何处理 Typecho Joe 主题被抄袭或盗版的问题
在开源社区中,版权保护是一个非常重要的话题。如果你发现自己的主题(如 Joe 主题)被其他主题(如子比主题)抄袭或盗版,你可以采取以下措施来维护自己的权益。 一、确认侵权行为 在采取任何行动之前…...

利用Vue和javascript分别编写一个“Hello World”的定时更新
目录 一、利用Vue编写一个“Hello World”的定时更新(1)vue编码在Html文件中(2)vue编码在js文件中 二、利用javascript编写一个“Hello World”的定时更新 一、利用Vue编写一个“Hello World”的定时更新 (1ÿ…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...