Description

你准备给弟弟 Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能被他排成有序形状的东西。
你准备给 Ike 买一个风铃。风铃是一种多层的装饰品,一般挂在天花板上。
每个风铃都包含一些由竖直线连起来的水平杆。每根杆的两头都有线连接,下面或者挂着另一根水平杆,或者挂着一个玩具。下面是一个风铃的例子:

为了满足弟弟,你需要选一个满足下面两个条件的风铃:

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

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

风铃可以按照下面的规则重新排列:任选一根杆,将杆两头的线“交换”。也就是解开一根杆左右两头的线,然后将它们绑到杆的另一头。这个操作不会改变更下面的杆上线的排列顺序。正在训练信息学奥林匹克的你,决定设计一个算法,判断能否通过重新排列,将一个给定的风铃变为 Ike 喜欢的样子。
考虑上面的例子,上图中的风铃满足条件(1),却不满足条件(2)——最左边的那个玩具比它右边的要高。
但是,我们可以通过下面的步骤把这个风铃变成一个 Ike 喜欢的:
第一步,将杆 1 的左右两边交换,这使得杆 2 和杆 3 的位置互换,交换的结果如下图所示:

第二步,也是最后一步,将杆 2 的左右两边交换,这使得杆 4 到了左边,原来在左边的玩具到了右边,交换的结果发下图所示:

现在的这个风铃就满足 Ike 的条件了。

你的任务是:给定一个风铃的描述,求出最少需要多少次交换才能使这风铃满足 Ike 的条件(如果可能)

Input

输入的第一行包含一个整数 n(1≤n≤100 000),表示风铃中有多少根杆。

接下来的 n 行描述杆的连接信息。这部分的第 i 行包含两个由空格分隔的整数 li和 ri,描述杆 i 的左右两边悬挂的东西。如果挂的是一个玩具,则对应的值为-1,否则为挂在下面的杆的编号

Output

输出仅包含一个整数。表示最少需要多少次交换能使风铃满足 Ike 的条件。如果不可能满足,输出-1。

Sample Input

6
2 3
-1 4
5 6
-1 -1
-1 -1
-1 -1

Sample Output

2


想法

才不会说我是看这个题目好玩才去做的呢
这个题目让我想起了林清玄的散文《风铃》:

有了风铃,风虽然吹过了,还留下美妙的声音
有了心的风铃,生命即使走过了,也会留下动人的痕迹
每一次起风的时候,每一步岁月的脚步,都会那样真实地存在。

等等,跑题了!

这个题就是树形dp嘛,注意判断几种不行的情况:
1.风铃相差层数>1
2.在满足风铃相差层数为1的情况下,把在上面一层的风铃统称为F,把下面一层的风铃统称为G
在某一节点,其两个子节点中都既有F又有G
然后注意各种细节就好了(自古树形dp细节多qwq)


代码

#include<cstdio>
#include<iostream>
#include<algorithm>using namespace std;const int N = 100005;int ch[N][2],pa[N],dep[N];
int n,rt;int m,d[N],t;
void get_dep(int u){for(int i=0;i<2;i++){if(ch[u][i]!=-1){dep[ch[u][i]]=dep[u]+1;get_dep(ch[u][i]);}else d[m++]=dep[u]+1,t=max(t,d[m-1]);}
}
int sz[N],num[N]; //num表示该节点子树中F与G的总和,sz表示该节点子树中F个数
void dfs0(int u){for(int i=0;i<2;i++){if(ch[u][i]!=-1){dfs0(ch[u][i]);num[u]+=num[ch[u][i]]; sz[u]+=sz[ch[u][i]];}else {num[u]++;if(dep[u]+1==t-1) sz[u]++;}}
}int flag;
int dfs(int u){if(sz[u]==0 || sz[u]==num[u]) return 0;if(ch[u][0]!=-1 && ch[u][1]!=-1){if(sz[ch[u][0]]==0) return dfs(ch[u][1]);if(sz[ch[u][1]]==0) return dfs(ch[u][0])+1;if(sz[ch[u][0]]==num[ch[u][0]]) return dfs(ch[u][1])+1;if(sz[ch[u][1]]==num[ch[u][1]]) return dfs(ch[u][0]);flag=0; return 0;}if(ch[u][0]==-1 && ch[u][1]!=-1){if(sz[ch[u][1]]==0) return 1;return dfs(ch[u][1])+1;}if(ch[u][0]!=-1 && ch[u][1]==-1){if(sz[ch[u][0]]==0) return 0;return dfs(ch[u][0]);}return 0;
}int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&ch[i][0],&ch[i][1]);if(ch[i][0]!=-1) pa[ch[i][0]]=i;if(ch[i][1]!=-1) pa[ch[i][1]]=i;}for(int i=1;i<=n;i++) if(!pa[i]) { rt=i; break; }dep[rt]=1; get_dep(rt);flag=1;for(int i=0;i<m;i++) if(d[i]<t-1) flag=0;if(flag==0) { printf("-1"); return 0; }dfs0(rt);if(sz[rt]==0) { printf("0"); return 0; }int ans=dfs(rt);if(flag==0) printf("-1");else printf("%d",ans);return 0;
}

转载于:https://www.cnblogs.com/lindalee/p/9074421.html

[洛谷P3621] [APIO2007] 风铃相关推荐

  1. 洛谷 P3620 - P3621 数据备份、风铃、动物园(APIO 2007)

    洛谷 P3620 - P3622 数据备份.风铃.动物园(2007 APIO) P3620 数据备份 题目描述: 思路: 我们先来将这道题简化一下: 将每一对相邻的建筑之间的空地看作一个点,点的权值即 ...

  2. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  3. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  4. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  5. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

  6. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

  7. 洛谷P1417 烹调方案

    洛谷P1417 烹调方案 如果是一般的01背包的话 选的先后是没关系的 但是这题选的先后是有关系的,因为他的价值是随着时间而变化的, 而你的01背包是做不到先选2再选1的 那么我们就跟国王游戏一样 用 ...

  8. 记忆优化搜索(简单题)(洛谷P3183 [HAOI2016]食物链 )( P5635 【CSGRound1】天下第一 )

    昨天做了蓝桥杯的时候,发现自己对于记忆优化搜索甚是不熟悉,所以今天随便找了几个基础题做做,顺便写下两片题解,顺便用了一下devc++敲的代码,发现没有代码补全真的可以说是灰常难受了... 洛谷P318 ...

  9. 洛谷 - 试炼场(全部题目备份)

    整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...

  10. 洛谷专题训练 ——【算法1-1】模拟与高精度

    洛谷题单[算法1-1]模拟与高精度 ACM-ICPC在线模板 题单链接: [算法1-1]模拟与高精度 下面的这一坨都是洛谷题单上的东东 题单简介 恭喜大家完成了第一部分语言入门,相信大家已经可以使用 ...

最新文章

  1. meetup_我在2017年举办Meetup中学到的知识以及为何对2018年充满期待。
  2. java.util.date_关于java中java.util.Date(急)
  3. C 一个数组删除一项 并且移位
  4. 分享26个关于Java开发视频教程(免费下载)
  5. 计算机软件基础操作,计算机软件基础 第九章 Excel基本操作(1页)-原创力文档...
  6. 【转】xargs命令详解,xargs与管道的区别
  7. FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解...
  8. TreeSet学习,比较器学习
  9. zoj 3629 Treasure Hunt IV
  10. 影响搜索引擎收录网站内容的四大原因分析
  11. 【转】[Python Tip]如何在Windows下方便地进入命令行运行程序
  12. 三维绘图之Mayavi.mlab
  13. smartsvn 8.6.6 for linux 的安装与破解
  14. Android studio中的一次编译报错’Error:Execution failed for task ':app:transformClassesWithDexForDebug‘,困扰了两天
  15. won10qualcomm atheros无线网卡驱动安装不了
  16. Internet Download Manager(V6.37版本IDM)免费序列号密钥激活版使用过程中的一些常见问题
  17. primeng使用步骤
  18. png转icon的一个软件
  19. 在linux中安装浏览器吗,教你如何在 Linux 中安装 Microsoft Edge 浏览器
  20. sql tuning advisor

热门文章

  1. Security+ 学习笔记4 社会工程攻击
  2. 国外NetDevOps资源工具清单分享
  3. OS之宏内核(Monolithic kernel)和微内核(Microkernel)详解
  4. NYOJ--41--三个数从小到大排序
  5. 青年歌手大奖赛_评委会打分 (一道比较简单的题目)
  6. 未来10年,将被人工智能/机器学习/大数据颠覆的三大行业
  7. DockOne微信分享(一四一):如何开发部署Kubernetes Native应用
  8. Nginx https configuration backed Certbot
  9. android 学习随笔二十三(动画:Fragment )
  10. 字典树(Trie树)的实现及应用