题目描述的实际是一颗二叉树,对于每个结点,要么满叉,要么无叉。

对于一种无解的简单情况,我们搜一遍树找到最浅的叶子结点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)的更多相关文章

  1. bzoj 1369: Gem 树形dp

    题目大意 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小.N<=10000 题解 我们可以 ...

  2. 【BZOJ 3090】 树形DP

    3090: Coci2009 [podjela] Description 有 N 个农民, 他们住在 N 个不同的村子里. 这 N 个村子形成一棵树.每个农民初始时获得 X 的钱.每一次操作, 一个农 ...

  3. bzoj 1131 简单树形dp

    思路:随便想想就能想出来啦把...  卡了我一个vector... #include<bits/stdc++.h> #define LL long long #define fi firs ...

  4. BZOJ 2651 城市改建 树形DP+模拟?

    题意 给一颗树,删除一条边再加一条边,使它仍为一颗树且任意两点间的距离的最大值最小. 题目数据范围描述有问题,n为1或重建不能使任意两点距离最大值变小,可以输出任意答案. 分析 删除一条边后会使它变成 ...

  5. bzoj 4987 Tree —— 树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4987 其实就是在树上找有 k 个点的连通块(路径上的点都选是最优的),之间的边都走了两遍,只 ...

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

  7. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  8. [BZOJ 1907] 树的路径覆盖 【树形DP】

    题目链接:BZOJ - 1907 题目分析 使用树形 DP,f[x][0] 表示以 x 为根的子树不能与 x 的父亲连接的最小路径数(即 x 是一个折线的拐点). f[x][1] 表示以 x 为根的子 ...

  9. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

随机推荐

  1. 北京Uber优步司机奖励政策(10月5日~10月11日)

    用户组:优步北京人民优步A组(适用于10月5日-10月11日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/ ...

  2. P1803 凌乱的yyy

    P1803 凌乱的yyy 题目背景 快noip了,yyy很紧张! 题目描述 现在各大oj上有n个比赛,每个比赛的开始.结束的时间点是知道的. yyy认为,参加越多的比赛,noip就能考的越好(假的) ...

  3. 两个有序数组合并成一个有序数组(要求时间复杂度为O(n))

    面试题: 怎样把两个有序数组合并成有序数组呢 逻辑步骤: 1.假设两个数组为A和B 2.A和B都是从小到大的顺序进行排列 ** 1.我们可以直接比较两个数组的首元素,哪个小就把这个小元素放入可变数组. ...

  4. K8S全栈容器服务如何助力企业云化创新?

    容器编排管理平台Kubernetes在实践两年多后,市场主导地位被正式确定,随着首批认证服务商的宣布,围绕着容器的应用编排部署服务已然成熟,Kubernetes开始在商业场景为企业创造价值.华为云在K ...

  5. 【WXS全局对象】Global

    Global对象的方法调用时,无需使用 Global.parseInt(...),而是直接使用 parseInt(...) 方法: 名称 说明 parseInt(string, radix) 解析一个 ...

  6. JAVA基础学习之路(二)方法定义,重载,递归

    一,方法的定义: package test; public class test1 { public static void main(String args[]) { int result = ad ...

  7. JavaScript 正则

    元字符 预定义类 边界 ^在中括号中时,匹配非hello的 str = 'hello world' str.match(/[^hello]/g) //[" ", "w&q ...

  8. python3中使用python2中cmp函数出现错误

    在python2中我们经常会使用cmp函数来比较一些东西,但是在python3中,你再来使用这个函数的时候,发现就报错了,提示找不到这个函数,这是为啥呢? 答:新版的python已经舍弃这种用法 而在 ...

  9. Juice账号

    zhangxiaocong69 zxc6545398 15657167502 区块链账户: 0x00680404766965143796a0a070835c3cdf9a4a50

  10. Python3 异常与断言

    1.异常 当出现错误时,程序就会发生异常 num1=input('Please input a num1: ') num2=input('Please input a num2: ') print(f ...