洛谷P3621风铃
分析:
这个题看起来像是个树形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风铃的更多相关文章
- [洛谷P3621] [APIO2007] 风铃
Description 你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西. 你准备给 Ike 买一个风铃.风铃是一种多层的装饰品,一般挂在天花 ...
- 洛谷 P3621 [APIO2007]风铃【贪心】
没有算法,但是要注意细节. 首先无解的情况,显然的是最小深度的叶子节点和最大深度的叶子节点的深度差大于1:还有一种比较难想,就是如果一个点的左右子树都有最大和最小深度的叶子节点,这样交换左右子树也不行 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷P1538迎春舞会之数字舞蹈
题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
随机推荐
- Java EE之JSTL(上)
1.JSP标签和JSTL简介 JSP标签看起来就像普通的HTML或者XML标签一样.一个JSP标签将执行某些操作. 为了引用JSP标签必须使用正确的XML命名空间. <%@ taglib pre ...
- oracle 11g 压缩数据文件
通过以下语句直接分析出每个数据库文件可压缩量 select a.file#, a.name, a.bytes CurrentMB, ceil(HWM ResizeTo, (a.bytes Releas ...
- bzoj 1825: [JSOI2010]蔬菜庆典
1825: [JSOI2010]蔬菜庆典 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 112 Solved: 45[Submit][Status][ ...
- 3532: [Sdoi2014]Lis 最小字典序最小割
3532: [Sdoi2014]Lis Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 865 Solved: 311[Submit][Status] ...
- Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)
Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...
- NDKr10的各种BUG
NDKr10有几个BUG,所以推荐使用NDKr9 bug1:不支持srand() bug2: 链接异常,找不到stpcpy()
- Shell记录-Shell命令(文件权限)
chmod命令用于改变linux系统文件或目录的访问权限.用它控制文件或目录的访问权限.该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1. 命令格式 ch ...
- Git记录-Git版本控制介绍
git config命令用于获取并设置存储库或全局选项.这些变量可以控制Git的外观和操作的各个方面. 如果在使用Git时需要帮助,有三种方法可以获得任何git命令的手册页(manpage)帮助信息: ...
- Windows下配置Nginx+php7
第一部分:准备工作 第二部分:安装nginx 第三部分:安装php(这里主要讲nginx配置启动php,以cgi运行php)nginx配置文件是conf文件夹里的nginx.conf 在这里,我简单说 ...
- vscode nodejs智能提示功能
1.依赖一些第三方的插件,先安装typings这个包,如果使用的是淘宝镜像,输入cnpm.cmd执行: cnpm i typings -g //cnpm install typings -global ...