传送门啦

分析:

这个题看起来像是个树形dp,嗯,就是看起来像。

所以我们就按树形dp的思路去分析就好了,这个题是一个树形dp的变形题。

和以前建树是一样的,我们用邻接表来进行储存。利用邻接表的特性,我们可以先加左边的点,再加右边的点,这样遍历的时候就可以先左后右了。

分析题意后我们设立几个数组:

(邻接表的就不说了,大家应该都会吧)

f [ i ] :表示使 i 这棵子树满足条件,所需要的最小的步数。

dep[ i ]:表示 i 这一个点的深度

maxdep[ i ]:表示 i 这个点的子树中风铃的最大深度

mindep[ i ]:同理表示 i 这个点的子树中风铃的最小深度

最后就是怎么样去写转移方程啦。

通过读题我们可以知道,在一棵树一定是一棵二叉树,所以我们就只需要将两棵子树相加就好了。

完成了???

并没有,我们是不是忘记了题目里的条件,题目中要求我们选一个满足下面两个条件的风铃:

(1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层。

(2) 对于两个相差一层的玩具,左边的玩具比右边的玩具要更靠下一点。

所以我们在状态转移方程里加一个小小的判断

if((abs(maxdep[c[]] - mindep[c[]]) > ) || (abs(mindep[c[]] - maxdep[c[]]) > ) || (maxdep[c[]] > mindep[c[]] && maxdep[c[]] > mindep[c[]])){

    printf("-1");
exit();
}

这次是真的完成了??

是哒

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = ; inline int read(){
int f = , x = ;
char ch = getchar();
while(ch > '' || ch < ''){if(ch == '-')f = -;ch = getchar();}
while(ch >= '' && ch <= ''){x = (x << ) + (x << ) + ch - '';ch = getchar();}
return x * f;
} int n,u,v;
struct Edge{
int from,to,next;
}edge[maxn << ];
int head[maxn],tot;
int f[maxn],w[maxn],cnt,c[maxn],dep[maxn];
int maxdep[maxn],mindep[maxn]; void add(int u,int v){
edge[++tot].from = u;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
} void dfs(int x,int fa){
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(v != fa){
dep[v] = dep[x] + ;
dfs(v , x);
mindep[x] = min(mindep[x] , mindep[v]);
maxdep[x] = max(maxdep[x] , maxdep[v]);
}
}
if(w[x] == -)
mindep[x] = maxdep[x] = dep[x];
else {
int num = ;
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(v != fa)
c[++num] = v;//两个儿子
}
if((abs(maxdep[c[]] - mindep[c[]]) > )
|| (abs(mindep[c[]] - maxdep[c[]]) > )
|| (maxdep[c[]] > mindep[c[]] && maxdep[c[]] > mindep[c[]])){
printf("-1");
exit();
}
f[x] = f[c[]] + f[c[]] + (mindep[c[]] < maxdep[c[]] ? : );
}
} int main(){
n = read();
cnt = n;
for(int i=;i<=n;i++){
u = read(); v = read();
if(v == -){
v = ++cnt;
w[cnt] = -;
}
add(v , i); add(i , v);
if(u == -){
u = ++cnt;
w[cnt] = -;
}
add(i , u); add(u , i);
}
memset(mindep , 0x3f , sizeof(mindep));
memset(maxdep , , sizeof(maxdep));
dfs( , );
printf("%d\n",f[]);
return ;
}

洛谷P3621风铃的更多相关文章

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

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

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

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

  3. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  6. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  7. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  8. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  9. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

随机推荐

  1. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  2. myeclipse2015修改web项目部署名

    在旧版本的myeclipse中修改web项目部署名很方便,直接右键在properties中查找web就能进行修改. 但是myeclipse2015中发现不能直接修改了. 我们可以点击config,或者 ...

  3. bzoj 4358: permu 莫队

    第一步先莫队分块. 对于每一块l~r,初始右端点设为r+1,然后每个询问先将右端点往右移,然后处理询问在l~r之间的部分,最后用一个栈再把l~r的复原. 具体来说是维护两个数组now1和now2,一个 ...

  4. An internal error occurred during: "Initializing Java Tooling". Eclipse启动发生的错误及解决办法

    1.关闭Eclipse.有时候不关闭eclipse 删除东西会引起其他莫名的错误. 2.删除 当前工作目录文件夹下的 /.metadata/.plugins/org.eclipse.core.reso ...

  5. aapt命令说明

    这里借用一下百度百科,我比较懒 1.列出apk包的内容 aapt l[ist] [-v] [-a] <你的应用> -v 以table形式列出来 -a 详细列出内容 例如:aapt l &l ...

  6. nltk_28Twitter情感分析模型

    sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...

  7. python中super与成员属性

    super的使用直接看例子: class A(): def __init__(self, a): print('init A...') self.a = a class B(A): def __ini ...

  8. openstack开发环境与代码测试

    一.openstack单组件开发环境 1.Python虚拟环境搭建 主要参考文献: https://virtualenv.pypa.io/en/latest/virtualenv.html 说明:Py ...

  9. [Apio2012]dispatching 主席树做法

    bzoj 2809: [Apio2012]dispatching http://www.lydsy.com/JudgeOnline/problem.php?id=2809 Description 在一 ...

  10. Bootstrap简单应用——对首页进行重构

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...