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. iOS开发之Objective-C与JavaScript的交互

    UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS ...

  2. 手把手教你 LabVIEW 串口仪器控制——VISA 驱动下载安装篇

           仪器控制,核心在于 VISA 函数..有些仪器可能不需要 VISA,有自己的 DLL 什么的,我就管不着.        正常情况下,大家安装的 LabVIEW,都是不带 VISA 驱动 ...

  3. java关于for循环。

    众所周知,JAVA中for循环的基本格式为: for(初始化表达式:布尔表达式:循环后更新表达式){循环体} 举个例子来说可以写成 (1)for (int x=1;x<10;x++){ Syst ...

  4. jvm垃圾收集器总结jdk1.7

    内存 ● 线程私有:程序计数器,虚拟机栈,本地方法栈 ● 线程共享: 方法区,堆 判断存活算法 ● 引用计数法:无法解决循环引用问题. ● 可达性分析算法: 从GCRoot作为起始点,向下搜索,经过的 ...

  5. Linux之用户与用户组

    1.Linux是一种 多用户多任务分时操作系统. 2.Linux的用户只有两个等级:root用户和非root用户.   Linux系统默认 内置了root用户 和一些非root用户,如nobody,a ...

  6. javascript实现浏览器窗口大小被改变时触发事件的方法

    转载 当浏览器的窗口大小被改变时触发的事件window.onresize 为事件指定代码: 复制代码代码如下: window.onresize = function(){ } 例如: 浏览器可见区域信 ...

  7. Mysql官方文档翻译系列14.18--MySql备份与恢复

    原文链接: (https://dev.mysql.com/doc/refman/5.7/en/innodb-backup-recovery.html) The key to safe database ...

  8. centos6.5中rpm包安装mysql5.7(初始化出错如何解决)

    下载rpm包见:http://www.cnblogs.com/grey-wolf/p/7472680.html 1.rz上传到服务器,解压缩 rz [root@mini2 upload]# -.el6 ...

  9. poj 2945 Find the Clones

    https://vjudge.net/problem/POJ-2945 题意: 给出n个长度相同的DNA序列,如果一个DNA序列出现过两次,那么就有说明它被复制了一次.问被复制0次,1次,2次--n- ...

  10. Windows10下的docker安装与入门 (一)使用docker toolbox安装docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...