题目传送门

细节较多的构造题。

解决思路

题目中虽然说是无根树,但我们可以钦定这棵树的根为 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. Java方法总结

    什么是方法 何谓方法 就是一个方法只完成一个功能,这样利于后期的扩展 例子: public static void main(String[] args) {    System.out.printl ...

  2. 报错:①Tog goal specified requires a project to execute but there is no POM in this directory......②说类HelloWorld是公共的, 应在名为 HelloWorld.java 的文件中声明 public class HelloWorld......

    在运行Maven的命令时,在DOS窗口里面必须把目录切换到项目的根部,要不然命令是找不到目的地. 下图是错误示范,项目在Demo02这个目录里,就必须将目录切换到Demo02下,否则DOS窗口只有飘红 ...

  3. 【读书笔记】C#高级编程 第十六章 错误和异常

    (一)简介 错误的出现并不总是编写应用程序的人的原因,有时应用程序会因为应用程序的最终用户引发或运行代码的环境而发生错误.C#提供了异常处理机制来处理错误. (二)异常类 在C#中,但刚出现某个特殊的 ...

  4. 高德地图与CAD图叠加显示方法汇总及优缺点分析

    前言 ​ 高德地图应用在许多领域,平常我们用的地图导航,除过正常的地图导航指引功能之外,其实还有很多实用的功能.如高德影像地图应用在包括地理.土地测量.水文学.生态学.气象学以及海洋学等方面.Auto ...

  5. Django 之路由层

    一.Django 请求周期生命流程图 首先,用户在浏览器中输入URL,发送一个GET 或 POST 方法的request 请求. Django 中封装了socket 的WSGI 服务器,监听端口接受这 ...

  6. .NET 反向代理 YARP 通过编码方式配置域名转发

    前面介绍了 YARP 通过配置文件的方式配置代理转发(传送门),而众所周知,微软的一贯作风就是能通过配置文件做的事情,通过编码的方式也能实现!YARP 也不例外,废话不多说,直接上代码! 首先,参照官 ...

  7. docker 生成mysql镜像启动时自动执行sql

    文章转载自:https://www.jianshu.com/p/12fc253fa37d 在docker 创建 mysql 容器时,往往需要在创建容器的过程中创建database 实例,代码如下: # ...

  8. 某宝抢购taobaosnap开发与实现

    某宝抢购脚本 Taobaosnap Taobaosnap is a completely open tool, which is used to buy goods in seconds on Tao ...

  9. 1-Mysql数据库简洁命令

    1-进入mysql数据库 mysql -u root -p 2-创建数据库 mysql> CREATE DATABASE serurities_master; mysql> USE ser ...

  10. PAT (Basic Level) Practice 1008 数组元素循环右移问题 分数 20

    一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0​A1​⋯AN−1​)变换为(AN−M​⋯AN−1​A0​A1​⋯AN ...