BZOJ 1149 风铃(树形DP)
题目描述的实际是一颗二叉树,对于每个结点,要么满叉,要么无叉。
对于一种无解的简单情况,我们搜一遍树找到最浅的叶子结点1和最深的叶子结点2,如果dep[1]<dep[2]-1,则显然无解。
所以现在所有的叶子结点的深度要么是dep[1]和dep[2].
我们可以把所有结点用node[x]标记状态。
node[x]=0表示x的子树下所有叶子结点深度都是dep[2]。
node[x]=1表示x的子树下一部分叶子结点深度是dep[1],一部分是dep[2]。
node[x]=2表示x的子树下所有叶子结点深度都是dep[1]。
现在有,假设x的儿子结点的node值都是1,则一定无解。证明是显然的。
假设x的左儿子结点node值大于右儿子结点的node值,则ans+1,表示需要操作一次。证明也是显然的。
另外node值可以通过一次树形DP得到,所以总复杂度为O(n).
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int pos, mi=INF, ma=, node[N*], dep[N*], n, ans, son[N][]; void dfs1(int x)
{
if (x>n) mi=min(mi,dep[x]), ma=max(ma,dep[x]);
else {
dep[son[x][]]=dep[son[x][]]=dep[x]+;
dfs1(son[x][]), dfs1(son[x][]);
}
}
bool dfs2(int x)
{
if (x>n) {
if (dep[x]<ma) node[x]=;
else node[x]=;
}
else {
if (dfs2(son[x][])== || dfs2(son[x][])==) return ;
if(node[son[x][]]==&&node[son[x][]]==) return ;
else if (node[son[x][]]==&&node[son[x][]]==) node[x]=;
else if (node[son[x][]]==&&node[son[x][]]==) node[x]=;
else {
if (node[son[x][]]>node[son[x][]]) ++ans;
node[x]=;
}
}
return ;
}
int main ()
{
int u, v;
scanf("%d",&n);
pos=n;
FOR(i,,n) {
scanf("%d%d",&u,&v);
if (u==-) u=++pos;
if (v==-) v=++pos;
son[i][]=u, son[i][]=v;
}
dfs1();
if (mi<ma-||dfs2()==) puts("-1");
else printf("%d\n",ans);
return ;
}
BZOJ 1149 风铃(树形DP)的更多相关文章
- bzoj 1369: Gem 树形dp
题目大意 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小.N<=10000 题解 我们可以 ...
- 【BZOJ 3090】 树形DP
3090: Coci2009 [podjela] Description 有 N 个农民, 他们住在 N 个不同的村子里. 这 N 个村子形成一棵树.每个农民初始时获得 X 的钱.每一次操作, 一个农 ...
- bzoj 1131 简单树形dp
思路:随便想想就能想出来啦把... 卡了我一个vector... #include<bits/stdc++.h> #define LL long long #define fi firs ...
- BZOJ 2651 城市改建 树形DP+模拟?
题意 给一颗树,删除一条边再加一条边,使它仍为一颗树且任意两点间的距离的最大值最小. 题目数据范围描述有问题,n为1或重建不能使任意两点距离最大值变小,可以输出任意答案. 分析 删除一条边后会使它变成 ...
- bzoj 4987 Tree —— 树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4987 其实就是在树上找有 k 个点的连通块(路径上的点都选是最优的),之间的边都走了两遍,只 ...
- BZOJ 4753 二分+树形DP
思路: 先二分答案 f[x][j]表示在x的子树里选j个点 f[x][j+k]=max(f[x][j+k],f[x][j]+f[v[i]][k]); 初始化 x!=0 -> f[x][1]=p[ ...
- [BZOJ 4033] [HAOI2015] T1 【树形DP】
题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...
- [BZOJ 1907] 树的路径覆盖 【树形DP】
题目链接:BZOJ - 1907 题目分析 使用树形 DP,f[x][0] 表示以 x 为根的子树不能与 x 的父亲连接的最小路径数(即 x 是一个折线的拐点). f[x][1] 表示以 x 为根的子 ...
- bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]
4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...
随机推荐
- JetBrains Makes its Products Free for Students(JetBrains 对学生免费了)
只要你有大学有些 后缀是 .edu的 如:@buaa.edu.cn,用你的邮箱注册,就可以免费试用 JetBrains了 下面是详细注册步骤: Hello everyone, If you’re o ...
- 长沙优步Uber奖励政策(7.27~8.2)
奖励前提 *必须满足当周评分4.7星及以上,且当周接单率70%及以上,才有资格获得奖励 *当周上线时间不低于7小时 *刷单和红线行为立即封号并取消当周全部奖励! *机场高速费用不参与翻倍奖励 *早高峰 ...
- clr via c#读书笔记五:常量和字段
1.常量是值从不变化的符号.只能定义编译器识别的基元类型的常量.如:Boolean,Char,Byte,SByte,Int16,UInt16,Int32,UInt32,Int64,Single,Dou ...
- SpringBoot-02:SpringBoot中的POM文件详细解释
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 我把pom文件,以及它的详细解释发出来 <?xml version="1.0" en ...
- Ruby数据类型
数字类型 书写整数时,可以根据需要在整数之间任意加入下划线而不会影响数字的值 a=123_45_78 puts a # => 12345678 to_i 截掉小数点之后的数字取整 内置Math模 ...
- C语言灵魂--指针
什么是指针?理解指针之前得知道什么是地址. 1.数据在计算机中的存储形式: 数据在计算机中是以二进制的形式存储的.计算机的存储器是用半导体集成电路构成的,有N多个二极管元件组成. 每一个二极管元件就如 ...
- 从零开始的Python学习Episode 2——运算符与while循环
一.算术运算符 加法:+,减法:-,乘法*,除法/,整除(地板除)//,取余%,乘方**. 二.逻辑运算符 且:and,或:or,非:not 优先级:not>and>or 短路原则: 对 ...
- FPGA学习-PS2接口
选自http://m.elecfans.com/article/774143.html
- nginx web服务器的安装使用
nginx是一个web服务器(高性能web服务器),类似于apache服务器和iis服务器,由于nginx服务器具有轻量级高并发的特点,目前nginx的使用已经超越了apache. nginx介绍:n ...
- Js全反选DataGrid
// **************************************************************** // // function Trim(value) // -- ...