题目链接

可能是个树上 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] 风铃的更多相关文章

  1. [APIO2007]风铃 --- 贪心

    [APIO2007]风铃 题目描述 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品, ...

  2. 题解:[APIO2007]风铃

    你需要选一个满足下面两个条件的风铃:(1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层.(2) 对于两个相差一层的玩具,左边的玩具比右边的玩具要更靠下一点. ...

  3. BZOJ1149:[CTSC/APIO2007]风铃——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1149 https://www.luogu.org/problemnew/show/P3621 sb ...

  4. [洛谷P3621] [APIO2007] 风铃

    Description 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品,一般挂在天花 ...

  5. 洛谷 P3621 [APIO2007]风铃【贪心】

    没有算法,但是要注意细节. 首先无解的情况,显然的是最小深度的叶子节点和最大深度的叶子节点的深度差大于1:还有一种比较难想,就是如果一个点的左右子树都有最大和最小深度的叶子节点,这样交换左右子树也不行 ...

  6. LuoguP3621 [APIO2007]风铃

    https://zybuluo.com/ysner/note/1140124 题面 题面复杂,戳我 解析 看着这道题... 似乎与[HNOI/AHOI2018]道路有不可言妙的相似之处. (题面吓人, ...

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

  8. dp方程

    1.        资源问题1 -----机器分配问题 F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2.        资源问题2 ------01背包问题   F[I,j]:=ma ...

  9. 基于Kinetic框架实现超酷的风铃悬挂摆动效果

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/iefreer/article/details/37049987 在踏得网开发过程中,我们在引导页面中 ...

随机推荐

  1. Linux安装配置vsftp搭建FTP的详细配置

    这里主要是说vsftp的配置:基础的可以参考Linux中VSFTP的配置 转自:https://www.jb51.net/article/103904.htm 修改配置文件 配置文件/etc/vsft ...

  2. 连接到 PostgreSQL 数据源(SQL Server 导入和导出向导)

    本主题向你介绍如何从 SQL Server 导入和导出向导的“选择数据源”页或“选择目标”页连接到 PostgreSQL 数据源. 重要 连接到 PostgreSQL 数据库的详细需求和先决条件不在此 ...

  3. c/c++ gdb 调试带参数的程序

    直接gdb pgname 参数1 这种方式,参数1是不会带到gdb里的 1,首先启动程序 gdb pgname 2,设置程序的参数 set args 参数1

  4. python进阶之正则表达式

    概念: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 目的? 给定一个正则表 ...

  5. c#操作SQL Server入门总结

    我是一名c#新手.本文只是我是常学习的随笔. 一.下载SQL server软件 听说下载开发板是最好的(开发板如果只是用来学习.研究不算是侵权).在安装的时候,我也遇到了很多问题,在公司的电脑安装第一 ...

  6. 面向对象_item项目

    详细见老师博客:http://www.cnblogs.com/Eva-J/articles/7351812.html#_label9 __getitem__\__setitem__\__delitem ...

  7. c#语法学习

    自动属性.隐试类型.命名参数和自动初始化器. note:这里说的这些,是语法糖.按照一定的格式写,部分代码编译器帮我们实现了, 1.自动属性:自动属性是非常有用的语法糖,帮我我们做了两件事:1.自动帮 ...

  8. Jetson TX2(2)ubutu1604--安装opencv3.4.0

    1安装OpenCV3.4.0+contrib 1 在终端中敲入以下两句sudo rm /var/cache/apt/archives/locksudo rm /var/lib/dpkg/lock su ...

  9. jenkins编译打包nodejs

    第一步 安装nodejs插件 第二步 在全局配置管理里面添加 nodejs配置 第三步 新建任务,从git上面拉取代码 cd /opt/tomcat7/bin/workspace/confdev #进 ...

  10. Selenium自动化测试之学会元素定位

    这是我经常被问到的一个问题,也是我很讨厌回答的问题,因为要想回答这个问题需要知道上下文.什么样式的元素,有哪些属性,是否有表单嵌套,都尝试了哪些定位方法...而且没几个提问者能事先详细的说明这些.哪儿 ...