[APIO2007] 风铃
题目链接
可能是个树上 DP?指针真好玩 23333。
首先对于所有玩具如果有深度差超过 1 的就是无解(在这里贡献 WA * 3),所以 dfs 一遍记录深度是有必要的……
然后如果有一个点的两颗子树中都含有最小、最大深度,那么这种情况也是无解,可以令同时含有两种深度的子树 tag = 1。
然后考虑最少交换次数,对于每一个节点的左右子树,三种情况需要交换:
1. 左边全是小深度的,右边全是大深度的
2. 左边全是小深度的,右边大小深度都有
3. 左边大小深度都有,右边全是大深度的
root->cnt = left_child->cnt + right_child->cnt + 本次是否需要交换(0 or 1)。
所以代码判的挺多的……
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = + ;
int n, in_deg[maxn], maxx, minn, ans, node_num; struct Node {
int deep, cnt, tag, type;
Node *lchild, *rchild; Node() { type = cnt = deep = , lchild = rchild = NULL; }
~Node() {};
} node[maxn], *p_root; inline int read() {
register char ch = ; register int w = , x = ;
while( !isdigit(ch) ) w |= (ch == '-'), ch = getchar();
while( isdigit(ch) ) x = (x * ) + (ch ^ ), ch = getchar();
return w ? -x : x;
} inline void Set_deep(Node *x) {
if( x->lchild != NULL ) x->lchild->deep = x->deep + , Set_deep(x->lchild);
if( x->rchild != NULL ) x->rchild->deep = x->deep + , Set_deep(x->rchild);
} inline void Deep_fs(Node *x) {
if( x->lchild == NULL && x->rchild == NULL ) return ;
if( x->lchild != NULL ) Deep_fs(x->lchild);
if( x->rchild != NULL ) Deep_fs(x->rchild);
if( x->lchild->tag && x->rchild->tag ) ans = -;
if( x->lchild->type ^ x->rchild->type ) x->tag = ;
else if( x->lchild->tag | x->rchild->tag ) x->tag = ;
else if( x->lchild->deep != x->rchild->deep ) x->tag = ;
x->cnt = x->lchild->cnt + x->rchild->cnt;
x->deep = max(x->lchild->deep, x->rchild->deep);
if( x->lchild->tag ^ x->rchild->tag ) {
if( x->lchild->tag && x->lchild->deep == x->rchild->deep ) ++x->cnt;
if( x->rchild->tag && x->lchild->deep < x->rchild->deep ) ++x->cnt;
} else if( x->lchild->deep < x->rchild->deep ) ++x->cnt;
} int main(int argc, const char *argv[])
{
freopen("..\\nanjolno.in", "r", stdin);
freopen("..\\nanjolno.out", "w", stdout); scanf("%d", &n), node_num = n, minn = 2e9;
for(int l, r, i = ; i <= n; ++i) {
l = read(), r = read();
if( l == - ) node[++node_num].type = , node[i].lchild = &node[node_num];
else node[i].lchild = &node[l], ++in_deg[l];
if( r == - ) node[++node_num].type = , node[i].rchild = &node[node_num];
else node[i].rchild = &node[r], ++in_deg[r];
}
for(int i = ; i <= n; ++i) if( in_deg[i] == ) p_root = &node[i];
p_root->deep = , Set_deep(p_root);
for(int i = ; i <= node_num; ++i) if( node[i].type ) {
maxx = max(maxx, node[i].deep), minn = min(minn, node[i].deep);
}
if( maxx - minn > ) puts("-1");
else Deep_fs(p_root), printf("%d\n", ans == - ? ans : p_root->cnt); fclose(stdin), fclose(stdout);
return ;
}
—— “从你慷慨的手里所付予的,我都接受。我别无所求。”
“是了,是了,我懂得你,谦卑的乞丐,你是乞求一个人的一切所有。”
[APIO2007] 风铃的更多相关文章
- [APIO2007]风铃 --- 贪心
[APIO2007]风铃 题目描述 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品, ...
- 题解:[APIO2007]风铃
你需要选一个满足下面两个条件的风铃:(1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层.(2) 对于两个相差一层的玩具,左边的玩具比右边的玩具要更靠下一点. ...
- BZOJ1149:[CTSC/APIO2007]风铃——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1149 https://www.luogu.org/problemnew/show/P3621 sb ...
- [洛谷P3621] [APIO2007] 风铃
Description 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品,一般挂在天花 ...
- 洛谷 P3621 [APIO2007]风铃【贪心】
没有算法,但是要注意细节. 首先无解的情况,显然的是最小深度的叶子节点和最大深度的叶子节点的深度差大于1:还有一种比较难想,就是如果一个点的左右子树都有最大和最小深度的叶子节点,这样交换左右子树也不行 ...
- LuoguP3621 [APIO2007]风铃
https://zybuluo.com/ysner/note/1140124 题面 题面复杂,戳我 解析 看着这道题... 似乎与[HNOI/AHOI2018]道路有不可言妙的相似之处. (题面吓人, ...
- dp式子100个……
1. 资源问题1-----机器分配问题F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2------01背包问题F[I,j]:=max(f[i- ...
- dp方程
1. 资源问题1 -----机器分配问题 F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2 ------01背包问题 F[I,j]:=ma ...
- 基于Kinetic框架实现超酷的风铃悬挂摆动效果
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/iefreer/article/details/37049987 在踏得网开发过程中,我们在引导页面中 ...
随机推荐
- win10 家庭版不支持gpedit.msc的解决办法
win10 家庭版不支持gpedit.msc的解决办法 1.建立一个批处理文件内容如下: @echo off pushd "%~dp0" dir /b %systemroot%\W ...
- 微信小程序——页面跳转及传参
小程序页面跳转 微信小程序的页面跳转依然是以传统的请求转发和请求重定向为主,tabbar的存在,有TAB页面的跳转. 为了微信小程序的简介方便,规定页面路径只能是十层,应尽量避免过多的交互方式. 1. ...
- Javascript DOM(2)
一.value属性操作 1.具有value属性的三个标签:input.select.textarea 2.value的获取:ele.value input=document.getElementByI ...
- nginx日志切割(logrotate或shell脚本)
nginx自己不会对日志文件进行切割,可以通过两种不同的方式进行,分别是:通过logrotate和通过shell脚本. 如果是yum方式安装的nginx,系统默认会自动通过logrotate这个日志管 ...
- Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法
Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 1. 卸载IE9( 装了Win7 64位后,默认 ...
- 详解vuex结合localstorage动态监听storage的变化
这篇文章主要介绍了详解vuex结合localstorage动态监听storage的变化,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 需求:不同组件间共用同一数据,当一个 ...
- styled components草根中文版文档
1.styled components官网网址 https://www.styled-components.com/docs 以组件的形式来写样式. 1.1安装 yarn add styled-c ...
- SP11470 TTM - To the moon
嘟嘟嘟 主席树+区间修改. 以为是水题,写着写着发现区间修改标记下传会出问题,然后想了想发现以前做的只是单点修改. 那怎么办咧? 然后题解交了我标记永久化这个神奇的东西. 特别好理解,就是修改的时候直 ...
- GIL全局解释器锁
1. 什么是GIL全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程 必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即 ...
- python小白——进阶之路——day3天-———运算符
(1)算数运算符: + - * / // % ** (2)比较运算符: > < >= <= == != (3)赋值运算符: = += -= *= /= //= %= ** ...