5100: [POI2018]Plan metra

Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special Judge
Submit: 189  Solved: 43
[Submit][Status][Discuss]

Description

有一棵n个点的无根树,每条边有一个正整数权值,表示长度,定义两点距离为在树上的最短路径的长度。
已知2到n-1每个点在树上与1和n的距离,请根据这些信息还原出这棵树。
 

Input

第一行包含一个正整数n(2<=n<=500000),表示点数。
第二行包含n-2个正整数d(1,2),d(1,3),...,d(1,n-1),分别表示每个点到1的距离。
第三行包含n-2个正整数d(n,2),d(n,3),...,d(n,n-1),分别表示每个点到n的距离。
输入数据保证1<=d<=1000000。
 

Output

若无解,输出NIE。
否则第一行输出TAK,接下来n-1行每行三个正整数u,v,c(1<=u,v<=n,1<=c<=1000000)
表示存在一条长度为c的连接u和v两点的树边。
若有多组解,输出任意一组。
 

Sample Input

7
6 6 2 2 1
5 3 5 1 4

Sample Output

TAK
1 5 2
5 7 1
5 2 4
7 3 3
1 4 2
1 6 1

HINT

 

Source

鸣谢Claris上传试题

构造题
分情况讨论
1. 1-n路径上没有其他点,即1与n直接相连
如果是这种情况,那么就有:对于任意一个点 i 1<i<n i到1与n的距离之差为一个定值a,a=1到n的边权
特判一下 每个点到 1和n的距离差是否相等就好
如果相等,可以直接把1和n相连 其它点都与1和n相连
如果不等,进入第二种情况

2. 1-n路径上还有点
我们可以找出这些点 这些点有一个共性:它们 到1与n的距离和 相等 且 比 不在1-n路径上的点 到1和n的距离和 小
找到这些点之后 其他点都可以通过与路径上的点相连来构造答案
如果一个点i与路径上某点相连 设它到1的距离为d1 到n的距离为dn

那么它到路径上某点(假设存在)的距离就是 w=(d1+dn-(1-n的距离))/2
/2是因为计算了2次 而如果w不能被整除的话,点i不能链接到树上

再判断路径上这个点是否存在,如果路径上不存在这个点,依旧没法把点i链接到树 判断条件 : 到1距离为d1-w的点存在于路径上

这样就一定可以构造出一棵合法树

#include<bits/stdc++.h>
#define N 500005
using namespace std;
int n,fg,mn=0x3f3f3f3f,fa[N],w[N],d1[N],dn[N],id[N<<]; inline char gc(){
static char s[],*p1,*p2;
if(p1==p2)p2=(p1=s)+fread(s,,,stdin);
if(p1==p2)return EOF;return *p1++;
}
inline int read(){
int x=;char ch=gc();
while(ch<''||ch>'')ch=gc();
while(ch>=''&&ch<='')x=x*+ch-'',ch=gc();
return x;
}
inline int solve1(){
int dis=abs(d1[]-dn[]);
if(!dis)return ;
for(register int i=;i<n;++i)
if(dis!=abs(d1[i]-dn[i]))return ;
puts("TAK");printf("%d %d %d\n",,n,dis);
for(register int i=;i<n;++i){
if(d1[i]<dn[i])printf("%d %d %d\n",i,,d1[i]);
else printf("%d %d %d\n",i,n,dn[i]);
}
return ;
} int main(){
n=read();if(n==){puts("TAK\n1 2 1");return ;}
for(register int i=;i<n;++i)d1[i]=read();
for(register int i=;i<n;++i){
dn[i]=read();
dn[i]+d1[i]<mn?mn=dn[i]+d1[i]:;
}
if(solve1())return ;
id[mn]=n;id[]=;
for(register int i=;i<n&&!fg;++i){
if(dn[i]+d1[i]==mn){
if(id[d1[i]])fg=;
else id[d1[i]]=i;
}
}
if(fg){puts("NIE");return ;}
for(register int i=;i<n&&!fg;++i){
if(d1[i]+dn[i]==mn)continue;
int tmp=d1[i],len=d1[i]+dn[i]-mn;
if(len&)fg=;len>>=;
tmp-=len;if(!id[tmp])fg=;
fa[i]=id[tmp];w[i]=len;
}
if(fg){puts("NIE");return ;}
int pre=;puts("TAK");
for(register int i=;i<=mn;++i){
if(!id[i])continue;
printf("%d %d %d\n",pre,id[i],i-d1[pre]);
pre=id[i];
}
for(register int i=;i<n;++i){
if(!fa[i])continue;
printf("%d %d %d\n",i,fa[i],w[i]);
}
return ;
}

bzoj5100 [POI2018]Plan metra 构造的更多相关文章

  1. 【BZOJ5100】[POI2018]Plan metra 构造

    [BZOJ5100][POI2018]Plan metra Description 有一棵n个点的无根树,每条边有一个正整数权值,表示长度,定义两点距离为在树上的最短路径的长度. 已知2到n-1每个点 ...

  2. bzoj千题计划249:bzoj5100: [POI2018]Plan metra

    http://www.lydsy.com/JudgeOnline/problem.php?id=5100 1.找到d1[i]+dn[i] 最小的点,作为1到n链上的点 2.令链长为D,若abs(d1[ ...

  3. BZOJ5100 : [POI2018]Plan metra

    若$1$到$n$之间没有其它点,则$1$到$n$的距离为任意一点到它们距离的差值,按照距离关系判断每个点是挂在$1$上还是挂在$n$上即可. 否则$1$到$n$的距离只可能为任意一点到它们距离和的最小 ...

  4. [POI2018]Plan metra

    题目大意: 一棵$n(n\le5\times10^5)$个结点的树,每条边的边权均为正整数,告诉你$2\sim n-1$号结点到$1$号点和$n$号点的距离$d1[i]$和$d2[i]$.求是否存在这 ...

  5. 题解【洛谷P5959】[POI2018]Plan metra

    题面 一道比较神仙的构造题. 首先确定 \(1\) 到 \(n\) 的路径长度,不妨设其长为 \(m\) . 通过观察发现,\(m\) 就是 \(\min_{1<i<n}\{dist_{1 ...

  6. [POI 2018] Plan Metra

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=5100 [算法] 首先分两类考虑 : 1. 1 -> N的路径不经过其它节点 , ...

  7. POI2018

    [BZOJ5099][POI2018]Pionek(极角排序+two pointers) 几个不会严谨证明的结论: 1.将所有向量按极角排序,则答案集合一定是连续的一段. 当答案方向确定时,则一个向量 ...

  8. BZOJ5100 POI2018Plan metra(构造)

    容易发现要么1和n直接相连,要么两点距离即为所有dx,1+dx,n的最小值.若为前者,需要满足所有|d1-dn|都相等,挂两棵菊花即可.若为后者,将所有满足dx,1+dx,n=d1,n的挂成一条链,其 ...

  9. HDU 4671 Backup Plan (2013多校7 1006题 构造)

    Backup Plan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...

随机推荐

  1. 日志 --BUG记录

    2014-12-15日 在做520wawa的免费推广   部署web应用时 错把path设置为"/*",导致启动tomcat时,导致错误 <Context path=&quo ...

  2. 3-51单片机WIFI学习(开发板8266底层源码介绍)

    上一篇链接  http://www.cnblogs.com/yangfengwu/p/8743502.html 直接上源码:注意源码有两部分,第一部分是一开始的时候写在模块内部的,另一部分是存在手机内 ...

  3. Python之协程

    前言 在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把cpu的利用率提高很多了.但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建 ...

  4. POJ2318【判断点在直线哪一侧+二分查找区间】

    题目大意:给定一个矩形和一些线段,线段将矩形分割为从左至右的若干部分,之后给出一些玩具的坐标,求每个部分中玩具的数量 #include<cstdio> #include<cstdli ...

  5. 测试驱动开发实践5————testSave之修改文档分类

    [内容指引] 1.确定"修改文档分类"的微服务接口及所需的参数 2.设计测试用例及测试用例合并 3.为测试用例赋值并驱动开发 上一篇我们通过17个测试用例完成了"新增文档 ...

  6. DataContractJsonSerializer序列化时间类型时转换为UTC溢出问题

    问题描述 如下一个实体类,含有非空时间类型属性,默认是C#的最小时间,在使用DataContractJsonSerializer将该类对象序列化成JSON时,抛出异常信息:System.Runtime ...

  7. angular中的路径问题

    我们在写项目时会遇到启动页调到引导页,引导页再调到首页, 那我们在用angular框架写这种东西的时候如果我们不细心的话就会遇到问题, 比如说找不到引导页的图片等等. 那我们怎么解决这个问题呢? 首先 ...

  8. TR069网管协议应用在Android系统开发的前言

    随着智能平台的终端设备不断发展,迫切需要我们解决这些终端的管理问题,而现有的终端统一管理平台已经成熟,主要是基于tr069协议网管平台,比如华为的itms等终端管理平台.所以,这篇文章就是为了实现一种 ...

  9. spark2.1:使用df.select(when(a===b,1).otherwise(0))替换(case when a==b then 1 else 0 end)

    最近工作中把一些sql.sh脚本执行hive的语句升级为spark2.1版本,其中遇到将case when 替换为scala操作df的方式实现的问题: 代码数据: scala> import o ...

  10. jacascript 鼠标事件和键盘事件

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 鼠标事件 鼠标事件共10类,包括click.contextmenu(右键).dblclick(双击).mo ...