原题链接:https://loj.ac/problem/2330

榕树之心

题目描述

深秋。冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子。相识数年的EvanEvan Evan 和 LyraLyraLyra 再次回到了小时候见面的茂盛榕树之下。小溪依旧,石桥依旧,榕树虽是历经荣枯更迭,依旧亭亭如盖,只是 EvanEvanEvan 和 LyraLyraLyra 再也不是七八年前不经世事的少年了。

……

“已经快是严冬了,榕树的叶子还没落呢……”

“榕树是常绿树,是看不到明显的落叶季节的……”

“唉……想不到已经七年了呢。榕树还是当年的榕树,你却不是当年的你了……”

“其实又有什么是一成不变的呢,榕树常绿,翠绿树冠的宏观永恒,是由无数细小树叶的荣枯更迭组成的。在时间的流逝中一切都在不断变化着呢……”

“但你看这榕树,日日如此,季季如此,年年如此,仿佛亘古不变般,盘根错节,郁郁葱葱。我在想,或许成为一棵树更好吧,任时间从枝叶间流过,我只守这一片绿荫就好。”

“榕树固然长久,但在这无限的时光里,终归是要湮灭于尘土的。与其像榕树一般,植根于一方泥土中感受年复一年的四季更替。倒不如在有限的时间里看过尽可能多的世界吧。再说了,榕树虽生长缓慢,却依旧会在每年春天抽出一根新的枝条去向外探索的呢……”

“真的吗,榕树在她漫长的一生里,就是这样往外一步步探索的吗?”

“毕竟就算树冠看起来一成不变,榕树也会随着时间周期变化,春天到了自然就是生长的时候了,她也应当做出对应的表现吧……”

“相比于对季节更替做出本能的生长,我倒宁愿相信,榕树有一颗活跃的的,探索的心。”

“其实榕树是有心的,榕树刚刚种下的时候,心就在根的地方发芽了。以后每年春天榕树长出新枝条的时候,心就会向着新枝条的方向移动一点,这样就能更靠近外面的世界了。你看这头顶上的枝条,纵横交错,其实心已经在这枝杈间,移动了数十载了呢……”

“哇,也就是说,这密密麻麻的树杈中的某个地方,藏着这棵榕树的心吗?”

“没错,可是要知道它在哪,就得另花一番功夫了……”

“呀,这时候想想,一株树还是不如一个人好……比如你,要是这样贴上去的话,就能听到跳动的声音呢……”

……

一棵榕树可以抽象成一棵nnn 个结点的有根树,其中结点编号为 1∼n" role="presentation" style="position: relative;">1∼n1∼n1 \sim n ,而 111 号点就是根节点。初始时,树只有1" role="presentation" style="position: relative;">111 号点,而心也在 111 号点。之后每一步,树都会长出一个新结点,即某个和当前已经存在的某个结点相邻的结点被加入了树中,之后,心会沿着心到新加结点的简单路径移动一步。这棵n" role="presentation" style="position: relative;">nn n 个结点的树有很多种生长的顺序,不同的顺序可能会导致最终心的位置不同。现在,EvanEvanEvan 和 LyraLyraLyra 想知道,哪些结点可能是心在生长过程结束时停留的位置呢?

例如一棵大小为 444 的树,连边为 {&lt;1,2&gt;,&lt;1,3&gt;,&lt;1,4&gt;}" role="presentation" style="position: relative;">{<1,2>,<1,3>,<1,4>}{<1,2>,<1,3>,<1,4>}\{,,\},我们有三种不同的生长顺序可以让心分别停留在 2,3,42,3,42,3,4 号节点上:

最终停留在 222 号点:

从 1" role="presentation" style="position: relative;">111 生长出 333,心从 1" role="presentation" style="position: relative;">111 移动到 333 ,
从 1" role="presentation" style="position: relative;">111 生长出 444,心从 3" role="presentation" style="position: relative;">333 移动回 111,
从 1" role="presentation" style="position: relative;">111 生长出 222,心从 1" role="presentation" style="position: relative;">111 移动到 222 .
最终停留在 3" role="presentation" style="position: relative;">333 号点:

从 111 生长出 2" role="presentation" style="position: relative;">222,心从 111 移动到 2" role="presentation" style="position: relative;">222 ,
从 111 生长出 4" role="presentation" style="position: relative;">444,心从 222 移动回 1" role="presentation" style="position: relative;">111 ,
从 111 生长出 3" role="presentation" style="position: relative;">333,心从 111 移动到 3" role="presentation" style="position: relative;">333 .
最终停留在 444 号点:

从 111 生长出 2" role="presentation" style="position: relative;">222,心从 111 移动到 2" role="presentation" style="position: relative;">222 ,
从 111 生长出 3" role="presentation" style="position: relative;">333,心从 222 移动回 1" role="presentation" style="position: relative;">111 ,
从 111 生长出 4" role="presentation" style="position: relative;">444,心从 111 移动到 4" role="presentation" style="position: relative;">444 .
而我们可以证明,不存在任何一种可能的生长顺序使得心停留在 111 号点。

输入格式

从标准输入读入数据。

输入第一行一个两个正整数 W,T" role="presentation" style="position: relative;">W,TW,TW, T,分别表示子任务编号(在样例中 W=0W=0W=0 )和数据组数,接下来是 TTT 组数据的描述,对于每组数据:

第一行一个正整数 n" role="presentation" style="position: relative;">nnn 表示树上结点的个数。

接下来n−1n−1 n−1 行,每行两个正整数 ai,biai,bia_i,b_i ,表示编号 ai,biai,bia_i,b_i 的结点间有一条树边,保证 ai≠biai≠bia_i \neq b_i​ 并且输入的n−1n−1n-1 条边恰好构成了一棵树。

输出格式

输出到标准输出。

若输入的 WWW 不等于 3" role="presentation" style="position: relative;">333,对于每组数据输出一行一个长度为 nnn 的 01" role="presentation" style="position: relative;">010101 字符串,表示编号为 1∼n1∼n1 \sim n 的结点是否有可能是心最后所在的位置,若 010101 字符串对应位是 111 则表示可能,为 0" role="presentation" style="position: relative;">000 则表示不可能。

若输入的WWW 等于 3" role="presentation" style="position: relative;">333,则对每组数据输出一个字符表示 111 号点的答案。

样例
样例输入 1

0 3
4
1 2
1 3
1 4
6
1 2
1 3
1 4
4 5
5 6
10
1 2
1 3
3 4
3 5
3 6
4 7
7 8
8 9
9 10

样例输出 1

0111
000101
0000001010

样例 2

见附加文件下的 ex_2.in 与 ex_2.ans。

数据范围与提示

Subtask 1[10pts]

T≤50;n≤15" role="presentation" style="position: relative;">T≤50;n≤15T≤50;n≤15T \leq 50; n \leq 15。

Subtask 2[10pts]

T≤20;n≤105T≤20;n≤105T \leq 20; n \leq 10^5​ 。 除了111号点之外,每个点度数(包括父亲)不超过2" role="presentation" style="position: relative;">222。

Subtask 3[10pts]

T≤200;n≤100T≤200;n≤100T \leq 200; n \leq 100。 只输出一个字符表示111号点答案,即保证1" role="presentation" style="position: relative;">111号点答案正确即可。

Subtask 4[35pts]

T≤20;n≤103T≤20;n≤103T \leq 20; n \leq 10^3​​ 。

Subtask 5[35pts]

T≤20;n≤105T≤20;n≤105T \leq 20; n \leq 10^5​ 。

题解

先考虑根节点能否被满足:

我们发现,对于以vvv为根节点的子树,假设“心”就在v" role="presentation" style="position: relative;">vvv处,“心”的移动是可以用vvv不同儿子的交错生长抵消的,最难消除的就是最大的儿子mx1[v]" role="presentation" style="position: relative;">mx1[v]mx1[v]mx1[v],我们可以先让mx1[v]mx1[v]mx1[v]内部自行抵消,设每个节点的子树最大程度抵消后剩余的生长数为remremrem,那么当rem[mx1[v]]≤siz[v]−1−siz[mx1[v]]rem[mx1[v]]≤siz[v]−1−siz[mx1[v]]rem[mx1[v]]\le siz[v]-1-siz[mx1[v]]时,我们就可以把mx1[v]mx1[v]mx1[v]的影响全部消除,除了siz[v]−1siz[v]−1siz[v]-1为奇数时会剩下一个节点的生长抵消不了,不然都能抵消。否则,rem[v]=rem[mx1[v]]−(siz[v]−1−siz[mx1[v]])rem[v]=rem[mx1[v]]−(siz[v]−1−siz[mx1[v]])rem[v]=rem[mx1[v]]-(siz[v]-1-siz[mx1[v]])。

凭借上述方式,我们就可以O(n)dfsO(n)dfsO(n)dfs一遍处理出整个remremrem数组,只需要查询rem[1]rem[1]rem[1]是否为000就可以得出根节点的答案。

那么对于其他的点,我们也可以用类似的方式解决,只需将1→v" role="presentation" style="position: relative;">1→v1→v1\to v的路径缩成一个点看做新的根节点即可:

然后类比一下根节点的做法搞一搞就好了。

代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
int T,W,n,id,siz[M],mx1[M],rem[M],mx2[M],dep[M],head[M],then[M<<1],ed[M<<1];
bool ans[M];
void add(int x,int y){then[++id]=head[x],head[x]=id,ed[id]=y;}
void in()
{id=0;memset(head,0,sizeof(head));for(int i=1;i<=n;++i)siz[i]=mx1[i]=mx2[i]=rem[i]=dep[i]=ans[i]=0;int a,b;scanf("%d",&n);for(int i=1;i<n;++i)scanf("%d%d",&a,&b),add(a,b),add(b,a);
}
void dfs1(int v,int f,int d)
{siz[v]=1;dep[v]=d;int to,oth;for(int i=head[v];i;i=then[i]){to=ed[i];if(to==f)continue;dfs1(to,v,d+1);siz[v]+=siz[to];if(siz[to]>=siz[mx1[v]])mx2[v]=mx1[v],mx1[v]=to;else if(siz[to]>siz[mx2[v]])mx2[v]=to;}oth=siz[v]-1-siz[mx1[v]];if(oth>=rem[mx1[v]])rem[v]=(siz[v]-1)%2;else rem[v]=rem[mx1[v]]-oth+1;
}
void dfs2(int v,int f,int maxn)
{int tot=n-dep[v],bs=(siz[maxn]>siz[mx1[v]]?maxn:mx1[v]),oth=tot-1-siz[bs],to;if(oth>=rem[bs])ans[v]=tot%2;else ans[v]=0;for(int i=head[v];i;i=then[i]){to=ed[i];if(to==f)continue;if(mx1[v]==to)dfs2(to,v,(siz[mx2[v]]>siz[maxn]?mx2[v]:maxn));else dfs2(to,v,bs);}
}
void ac()
{dfs1(1,0,0);dfs2(1,0,0);printf("%d",rem[1]?0:1);if(W!=3)for(int i=2;i<=n;++i)printf("%d",ans[i]);putchar(10);
}
int main()
{scanf("%d%d",&W,&T);while(T--)in(),ac();
}

LOJ2330「清华集训 2017」榕树之心相关推荐

  1. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  2. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...

  3. 【清华集训2017】榕树之心

    简要题意:(考虑到某些人搜题解只是懒得看题面) 特殊点从 \(1\) 号点出发,每次选择一个与当前选择连通块相连的点,加入连通块,并且把我们的特殊点向那个选的点移动一格.对每个点求是否能成为我们的特殊 ...

  4. 「清华集训 2017」某位歌姬的故事

    题目链接 问题分析 吐槽一下这个预处理比DP还长的题-- 首先对限制从小到大排序,然后不难发现对于每一种大小限制都是独立的.离散后考虑\(F[i][j]\)表示以\(i\)结尾,上一个音高为限制大小的 ...

  5. 清华集训2017刷题记录

    2322. 「清华集训 2017」Hello world! 题意 一棵树每个点有点权,每次可以选择两个点\(s, t\),选择步长为\(k\),从\(s\)跳到\(t\)(不足\(k\)步直接到\(t ...

  6. 「清华名师讲坛」推荐

    在「清华名师讲坛」中我们可以看见两条「桥」,一条是跨越人文与科学的桥,一条是跨越中.西的桥. 这两条桥正好说明了清华大学的特质.清华无疑地是中国理工类大学的翘楚,是中国科学研究令人生敬的殿堂,但它也拥 ...

  7. 清华集训2017题解

    ioi赛制好评QAQ 好像啥都记不得了就不写游记了 Day 1 1.1 生成树计数(tree.cpp) 1.1.1. 题意 ​ 有 n≤30000n≤30000 n \le 30000 个点,第 ii ...

  8. 姚期智的「清华十年」

    2004年9月的一天,正在普林斯顿大学攻读博士学位的张胜誉像往常一样与导师姚期智碰面交流近期研究进展.姚期智突然对他说:"我要回中国了,permanently(永远地)." 张胜誉 ...

  9. 【luogu P4005 清华集训2017】小Y和地铁

    题目描述 小 Y 是一个爱好旅行的 OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的一条曲线,不同线路的交点处一定会设有 换乘站 . ...

  10. JZOJ 5490. 【清华集训2017模拟11.28】图染色

    Description Input 第一行包括两个整数N,M. 接下来M行每行两个整数u,v,代表存在一条里连接 u,v的无向边.可能存在重边自环. Output 降序输出所有不为0的F(i) .保留 ...

最新文章

  1. 每天学一点儿shell:Linux三剑客——awk命令
  2. escape in ABAP and JavaScript
  3. iOS-生成二维码图片【附中间带有小图标二维码】(QRCode)
  4. Python gmpy2 mpz Methods
  5. Java高并发BlockingQueue重要的实现类二
  6. 计算机信息管理系统实训摘要,计算机实训报告摘要.doc
  7. 一元三次方程c语言程序,一元三次方程求解
  8. 把txt 转换成CHM的目录或Index
  9. java log 乱码_Java日志文件乱码
  10. 电热毯UL964标准上架亚马逊所需资料流程
  11. 京东疯狂月薪36k程序员最新Java面试题(常见面试题及答案汇总)
  12. 量化交易软件该怎么选择
  13. 数据库 Table is marked as crashed and should be repaired 解决办法
  14. c#中文件路径出现非法字符怎么办?解决也容易
  15. 如何治理VOCs有机废气的方法——吸附
  16. html图片叠,很棒的CSS3图片堆叠效果
  17. 进程的通信 - 剪切板
  18. 电脑能正常上网,但是不能连接共享的打印机 电脑无法打印 服务打开无法打印
  19. Visual C++ 2010创建Ribbon界面(上)
  20. matlab通信工具comm,comm matlab上最全的通信模块,包括各种调制方式和信道特性, 编码函数 256万源代码下载- www.pudn.com...

热门文章

  1. 242.有效的字母异位词(力扣leetcode) 博主可答疑该问题
  2. 503.下一个更大元素II(力扣leetcode) 博主可答疑该问题
  3. java读取配置文件的详细写法,Properties配置文件读取相关java知识
  4. [UNIX]The UNIXHATERS Handbook
  5. Java编程:切面条
  6. Python_pip_03_安装模块出现错误时咋整
  7. USACO 3.3 Riding the Fences(欧拉路输出路径)
  8. Unity3D调用外部程序
  9. HashSet原理、TreeSet
  10. ThreadLocal原理、ThreadLocal内存泄漏