题面传送门

解决思路

题目中虽然说是无根树,但我们可以钦定这棵树的根为节点 \(1\),方便构造,这是不

影响结果的。

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

先考虑无解的情况。

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

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

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

然后考虑如何构造。

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

一种比较简单的想法:

给一组例子:

10 5 5 4

首先把节点 \(2\) 和节点 \(3\) 可以公共的部分输出。公共祖先数 (不包括节点 \(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. 题解:CF593D Happy Tree Party

    题解:CF593D Happy Tree Party Description Bogdan has a birthday today and mom gave him a tree consistin ...

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

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

  4. hdu6121 Build a tree 模拟

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

  5. hdu6121 Build a tree

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

  6. PAT甲题题解1099. Build A Binary Search Tree (30)-二叉树遍历

    题目就是给出一棵二叉搜索树,已知根节点为0,并且给出一个序列要插入到这课二叉树中,求这棵二叉树层次遍历后的序列. 用结构体建立节点,val表示该节点存储的值,left指向左孩子,right指向右孩子. ...

  7. 题解-AtCoder Code-Festival2017 Final-J Tree MST

    Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...

  8. 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− ...

  9. 题解 CF383C 【Propagating tree】

    这道题明明没有省选难度啊,为什么就成紫题了QAQ 另:在CF上A了但是洛谷Remote Judge玄学爆零. 思路是DFS序+线段树. 首先这道题直观上可以对于每一次修改用DFS暴力O(n),然后对于 ...

随机推荐

  1. 播放器之争:VLC还是martPlayer

    好多开发者跟我们交流的时候提到,为什么有了VLC这种开源播放器,大牛直播SDK还要开发SmartPlayer?以下就针对VLC和SmartPlayer功能支持和涉及侧重,做个大概的比较: VLC VL ...

  2. KingbaseES 命令行安装数据库

    关键字: ​ KingbaseES.Linux.x86-64 一.安装前环境准备 1.硬件环境支持 ` 金仓数据库管理系统KingbaseES支持X86.X86_64,同时支持龙芯.飞腾等国产CPU硬 ...

  3. 高阶 CSS 技巧在复杂动效中的应用

    最近我在 CodePen 上看到了这样一个有意思的动画: 整个动画效果是在一个标签内,借助了 SVG PATH 实现.其核心在于对渐变(Gradient)的究极利用. 完整的代码你可以看看这里 -- ...

  4. 04-MyBatisPlus条件构造器

    一.wapper介绍 Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件 QueryWrapper : Entit ...

  5. haodoop高可用

    高可用简介 Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似, 但 HDFS NameNode 对数据存储及其一致性的要求比 ...

  6. 详解字符编码与 Unicode

    人类交流使用 A.B.C.中 等字符,但计算机只认识 0 和 1.因此,就需要将人类的字符,转换成计算机认识的二进制编码.这个过程就是字符编码. ASCII 最简单.常用的字符编码就是 ASCII(A ...

  7. Java SE Object类

    1.Object类 equals 方法 == 和 equals 的对比 == 是一个比较运算符 == 既可以判断基本类型,又可以判断引用类型 == 如果判断的是基本类型,判断的是值是否相等 == 如果 ...

  8. docker-compose安装harbor

    目录 Harbor 安装环境说明 获取安装包(离线安装方式) 安装harbor 用docker-compose查看Harbor容器的运行状态 Harbor访问测试 上传镜像到Harbor服务器 Har ...

  9. 通过nginx转发rabbitmq访问手动添加队列的时候报错:Management API returned status code 405

    原因: 正常访问该地址:https://xxx.xxx.com/rabbitmq/ 时能正常跳转,但是 rabbitmq management 的 API url 出现了 %2f 字符,这些字符会在经 ...

  10. jenkins邮箱配置