题目传送门

细节较多的构造题。

解决思路

题目中虽然说是无根树,但我们可以钦定这棵树的根为 1,方便构造,这是不影响结果的。

以下记给定的三段长度为 \(a,b,c\) 。

先考虑无解的情况。

  • 首先,给出的三个距离,任意两者之和必须大于等于第三者,否则显然无解。

  • 其次,用到的边数不能\(\ge n\)。

  • 最后,两个节点的 \(\text{LCA}\) 到根节点的距离 (绿色) 是整数,两节点之间最短距离 (蓝色) 也是整数,而 \(a+b+c\) 正好是蓝色绿色各算两次,所以 \(a+b+c\) 必须是偶数。

然后考虑如何构造。

为了方便,我们钦定 2 离根节点距离较小的一个。可以事先比较并做交换,输出时修改一下。

一种比较简单的想法:

给一组例子:

10 5 5 4

首先把 23 可以公共的部分输出。公共祖先数 (不包括 1) 可以这样

算: \((a+c-b)/2\)(想一想为什么)。输出的 \(now\) (当前填充节点)应该从 4 开始,\(lst\)(上一个节点)初始设为 1,之后每一次将 \(lst\) 更新为 \(now\),然后将 \(now +1\) 。

处理完会变成这样:

然后从当前扩展到的节点分别向两侧延伸,记已经输出的公共祖先数为 \(cnt\),那么 2 还需拓展的点数为 \(a-cnt-1\),3 还需拓展的点数为 \(b-(a-cnt)-1\) 。像之前一样分别向两边拓展即可。注意拓展 2 之前先把 \(lst\) 暂存下来,方便之后拓展 3 时将 \(lst\) 归位。

处理完会变成这样:

最后还剩的点全部连到 1 上即可(连其他地方也没事)。

所以这个样例最后一组可行的解就是这样:

先给出这一部分的代码:

int _1=2,_2=3;
if(a>c){
swap(a,c);
swap(_1,_2);
}
int lst=1,now=4,cnt=0;
for(int i=1;i<=(a+c-b)/2;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++,cnt++;
}
a-=cnt,c-=cnt;
int t1=lst;
for(int i=1;i<a;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_1<<endl;
lst=t1;
for(int i=1;i<b-a;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_2<<endl;
for(int i=now;i<=n;i++) cout<<1<<' '<<i<<endl;

然而这样写却 \(\text{WA}\) 了。对照错误样例 通过仔细思考,我们可以发现一种特殊情况,比如:

6 2 3 5

这时,以上的程序给出了一个离谱的错误答案。手玩发现,这种特殊情况是整棵树恰好为一条链:

这时,较近的点为较远的点的祖先,也就是 \(a+b=c\) 。

所以,只需要特判出来,按照链的特点,用类似方法构造即可。

AC Code

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
using namespace std;
int T,n,a,b,c,d1,d2,d3;
void solve(){
cin>>n>>a>>b>>c;
d1=(a+c-b)/2;
d2=(a+b-c)/2;
d3=(b+c-a)/2;
if(d1<0||d2<0||d3<0||d1+d2+d3>=n||(a+b+c)%2){
cout<<"NO"<<endl;
return ;
}
cout<<"YES"<<endl;
int _1=2,_2=3;
if(a>c){
swap(a,c);
swap(_1,_2);
}
int lst=1,now=4,cnt=0;
if(a+b==c){
for(int i=1;i<a;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_1<<endl;
lst=_1;
for(int i=1;i<b;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_2<<endl;
}
else{
for(int i=1;i<=(a+c-b)/2;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++,cnt++;
}
a-=cnt,c-=cnt;
int t1=lst;
for(int i=1;i<a;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_1<<endl;
lst=t1;
for(int i=1;i<b-a;i++){
cout<<lst<<' '<<now<<endl;
lst=now,now++;
}
cout<<lst<<' '<<_2<<endl;
}
for(int i=now;i<=n;i++) cout<<1<<' '<<i<<endl;
}
int main(){
IOS;TIE;
cin>>T;
while(T--) solve();
return 0;
}

【笔记】CF1714F Build a Tree and That Is It 及相关的更多相关文章

  1. 【题解】CF1714F Build a Tree and That Is It

    题面传送门 解决思路 题目中虽然说是无根树,但我们可以钦定这棵树的根为节点 \(1\),方便构造,这是不 影响结果的. 以下记给定的三段长度为 \(a,b,c\). 先考虑无解的情况. 首先,给出的三 ...

  2. HDU 6121 Build a tree(找规律+模拟)

    Build a tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)To ...

  3. hdu6121 Build a tree 模拟

    /** 题目:hdu6121 Build a tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题意:n个点标号为0~n-1:节点i的父节点 ...

  4. hdu6121 Build a tree

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6121 题面: Build a tree Time Limit: 2000/1000 MS (J ...

  5. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  6. 2017ACM暑期多校联合训练 - Team 7 1002 HDU 6121 Build a tree (深搜+思维)

    题目链接 Problem Description HazelFan wants to build a rooted tree. The tree has n nodes labeled 0 to n− ...

  7. HDU 6121 Build a tree —— 2017 Multi-University Training 7

    HazelFan wants to build a rooted tree. The tree has nn nodes labeled 0 to n−1, and the father of the ...

  8. Vue.js学习笔记(6)tree

    分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望和小颖分享下.嘻嘻 啦啦啦,代码看这里喽: <div class=" ...

  9. 机器学习技法笔记:09 Decision Tree

    Roadmap Decision Tree Hypothesis Decision Tree Algorithm Decision Tree Heuristics in C&RT Decisi ...

随机推荐

  1. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  2. 解决QIcon引用qrc不显示图片

    引用Qrc 对于Qt来说,添加qrc之后,可以使用":"来直接访问qrc的文件,比如 QIcon icon(":/icon/red.png"); 绝对路径 当然 ...

  3. 如何用 refcursor 返回结果集

    可以通过返回 Refcursor 类型的函数,或者out 类型的函数或 procedure 返回结果集. 一.返回refcursor 类型的函数 create or replace function ...

  4. KingbaseES 如何实现Oracle pipelined 功能

    管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其赋值给集合变量.KingbaseES 数据库可以用 setof 实 ...

  5. Java 热更新 Groovy 实践及踩坑指南

    Groovy 是什么? Apache的Groovy是Java平台上设计的面向对象编程语言.这门动态语言拥有类似Python.Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用 ...

  6. 使用 Elastic 技术栈构建 K8S 全栈监控 -4: 使用 Elastic APM 实时监控应用性能

    文章转载自:https://www.qikqiak.com/post/k8s-monitor-use-elastic-stack-4/ 操作步骤 apm-servver连接es使用上一步创建的secr ...

  7. 3_Nginx

    一. Nginx介绍 1.1 引言 为什么要学Nginx 问题1: 客户端到底要将请求发送给哪台服务器 问题2: 如果所有客户端的请求都发送给了服务器1 问题2: 客户端发送的请求可能是申请动态资源的 ...

  8. 在项目中自定义集成IdentityService4

    OAuth2.0协议 在开始之前呢,需要我们对一些认证授权协议有一定的了解. OAuth 2.0 的一个简单解释 http://www.ruanyifeng.com/blog/2019/04/oaut ...

  9. C#-7 结构和枚举

    一 什么是结构 结构是程序员定义的数据类型,有数据成员和函数成员,和类非常类似. 类是引用类型,而结构是值类型: 结构和类一样可以实现接口: 结构是隐式密封的,不能被派生: 结构类型的变量不能为nul ...

  10. img通过修改css等比例缩小图片

    css中加上:object-fit:cover 例子: img{ width: 200px; height: 400px; object-fit: cover; }