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

对于一种无解的简单情况,我们搜一遍树找到最浅的叶子结点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司机奖励政策(8月24日到8月30日)

    本周奖励(8月24日到8月30日) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://w ...

  2. 4 进程间通信Queue [kjuː]

    1.进程间通信-Queue Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信. 说明 初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数 ...

  3. 用python读取配置文件config.ini

    还在学习中...写的有点凌乱 感觉还是应该先学会读取配置文件才行,把一些经常需要修改的但是又经常需要用到的参数放到配置文件中方便使用(我是这么觉得的) 首先是config.ini的存放位置,我们把它放 ...

  4. Appium-测试失败后屏幕截图的

    本文参考:http://www.cnblogs.com/hexianl/p/4958556.html 使用testng测试框架进行管理测试 1.创建监听,代码如下: import io.appium. ...

  5. Siki_Unity_1-8_使用Unity开发2D游戏_PongGame

    Unity 1-8 使用Unity开发2D游戏 PongGame 任务1:演示 http://pan.baidu.com/s/1pKUHsev; up2i 任务2:案例介绍 创建PongGame,注意 ...

  6. Siki_Unity_1-6_C#编程初级教程(未学)

    Unity 1-6 C#编程初级教程 任务1:C#和.Net框架 C#是.Net里的一个成分 2002年微软发布第一个.Net框架(多平台,行业标准,安全性) .Net框架 IDE编程工具 --产生- ...

  7. [JSON].set(keyPath, value)

    语法:[JSON].set( keyPath, value ) 返回:[True | False] 说明:设置键值 参数: keyPath    [keyPath 必需] 键名路径字符串 value ...

  8. lintcode433 岛屿的个数

    岛屿的个数 给一个01矩阵,求不同的岛屿的个数. 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右为相邻. 您在真实的面试中是否遇到过这个题? Yes 样例 在矩阵: ...

  9. PHP计算两个已知经纬度之间的距离

    /** *求两个已知经纬度之间的距离,单位为千米 *@param lng1,lng2 经度 *@param lat1,lat2 纬度 *@return float 距离,单位千米 **/ privat ...

  10. Centos7下安装mysql服务

    yum install -y perl-Module-Install.noarch yum -y install perl perl-devel #命令下载mysql wget http://dev. ...