题意:

很久很久以前,有一棵树加入了 UOJ 群。

这天,在它讨论“一棵树应该怎么旋转”的时候一不小心被删除了,变成了被删除的树。

突然间,它突然发现它失去了颜色,变成了一棵纯白的树。这让它感觉很焦躁,于是它来拜托你给自己染上一些颜色。

我们可以把它描述成一棵n个节点的有根树(默认树的根为1号节点),所有非根的度数为1的节点被称为叶子节点。最开始所有的点都是白色的。

现在你需要选出一些节点并把这些节点染成黑色的。为了迎合树的审美,你的染色方案必须要满足所有叶子节点到根路径上的黑色节点个数相同。

你发现黑色节点个数越多,树就会越高兴,所以你想要知道在所有合法的染色方案中,黑色节点总个数最多是多少。

题解:

神题。(感觉UOJ Round的题全是神题)

$O(n^2)$的DP大家都会,但是跟正解并没有什么关系;

显然题目要求相当于使白色节点最少;

有几个结论:

1.如果一种合法方案中根节点到所有叶节点的路径上都经过白色节点,那么dfs一遍这棵树,在遇到白色节点时染黑并回溯,这样必定可以使得白色节点变少或不变且依然合法;

2.如果一种合法方案中根节点到深度最浅的叶节点的路径上经过白色节点,那么根节点到所有叶节点的路径上必定都经过白色节点;假定根节点深度为1,因为其他叶节点的深度不小于到最浅叶节点的深度,而根节点到其他叶节点路径上的黑节点数等于到最浅叶节点路径上的黑节点数,而小于他们的深度,因此根节点到其他叶节点的路径上都会经过至少一个白点;

综上,一种最优的合法方案必定满足根节点到最浅叶节点的路径上没有白点;

这样一种构造方法就是先把根节点到最浅叶节点的路径全部染黑,然后递归判断根节点的其他子树跟是否要染白再往下做即可;

简化到每个点,实际上一个点被染白当且仅当该节点子树中最浅叶节点的深度>整棵树的最浅叶节点深度+该节点到根节点路径上的白点个数;

预处理每个点子树中的最浅叶节点深度,再一次dfs判断即可,时间复杂度$O(n)$。

代码:

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
typedef double db;
struct edge{
int v,next;
}a[];
int n,u,v,ans=,tot=,du[],mid[],head[];
void add(int u,int v){
a[++tot].v=v;
a[tot].next=head[u];
head[u]=tot;
}
void dfs(int u,int fa,int dpt){
if(u!=&&du[u]==)mid[u]=dpt;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa){
dfs(v,u,dpt+);
mid[u]=min(mid[u],mid[v]);
}
}
}
void _dfs(int u,int fa,int nwd){
if(nwd<mid[u]){
nwd++;
ans++;
}
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa){
_dfs(v,u,nwd);
}
}
}
int main(){
memset(head,-,sizeof(head));
memset(mid,0x7f,sizeof(mid));
memset(du,,sizeof(du));
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
du[u]++,du[v]++;
}
dfs(,,);
_dfs(,,mid[]);
printf("%d",n-ans);
return ;
}

【UOJ139】【UER #4】被删除的黑白树的更多相关文章

  1. 【uoj#139】[UER #4]被删除的黑白树 贪心

    题目描述 给出一个 $n$ 个节点的树,$1$ 号点为根.现要将其中一些点染成黑色,使得每个叶子节点(不包括根节点)到根节点路径上的黑点数相同.求最多能够染多少个黑点. 题解 贪心 显然有结论:选择的 ...

  2. uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心

    #139. [UER #4]被删除的黑白树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/139 Descript ...

  3. 【UOJ139】【UER #4】被删除的黑白树(贪心)

    点此看题面 大致题意: 请你给一棵树黑白染色,使每一个叶结点到根节点的路径上黑节点个数相同. 贪心 显然,按照贪心的思想,我们要让叶结点到根节点的路径上黑节点的个数尽量大. 我们可以用\(Min_i\ ...

  4. uoj139 【UER #4】被删除的黑白树

    题目 不难发现有一个暴力\(dp\) 设\(dp[x][l]\)表示\(x\)点子树内所有叶子节点到\(x\)的路径上都有\(l\)和黑点时最多能染多个黑点 转移就是 \[dp[x][l]=\max( ...

  5. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  6. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  7. [BZOJ 3319] 黑白树

    3319: 黑白树 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 557  Solved: 194[Submit][Status][Discuss] ...

  8. CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】

    [编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1.树上每个节点i对应一个值k[i].每个点都有一个颜色,初始的时候所有点都是白色 ...

  9. 【BZOJ3319】黑白树 并查集

    [BZOJ3319]黑白树 Description 给定一棵树,边的颜色为黑或白,初始时全部为白色.维护两个操作:1.查询u到根路径上的第一条黑色边的标号.2.将u到v    路径上的所有边的颜色设为 ...

随机推荐

  1. CAN在汽车电子中的应用

    http://xuxiaozhao163.blog.163.com/blog/static/3793592200802784146452/ CAN是控制器局域网络(Controller Area Ne ...

  2. find-median-from-data-stream & multiset priority queue 堆

    https://leetcode.com/problems/find-median-from-data-stream/ 这道题目实在是不错,所以单独拎出来. https://discuss.leetc ...

  3. hdu5355 思维+爆搜

    pid=5355">http://acm.hdu.edu.cn/showproblem.php?pid=5355 Problem Description There are m sod ...

  4. 黑马程序猿——JAVA基础——集合

    ----------android培训.java培训.java学习型技术博客.期待与您交流.------------  一.关于java中的集合类        首先看一下,大致的框架流程图     ...

  5. Codeforces Round #200 (Div. 2)D. Alternating Current (堆栈)

    D. Alternating Current time limit per test 1 second memory limit per test 256 megabytes input standa ...

  6. Linux命令(六)——软件包管理(安装应用程序)

    与windows安装各种应用程序相似,在linux下也可以安装各种需要的应用程序,通常称为软件包.目前,在linux系统下常见的软件包格式主要有:RPM包.TAR包.bz2包.gz包.deb包.sh结 ...

  7. js自定义回调函数

      JavaScript允许开发人员像传递任何类型的数据一样传递函数,也就是说,函数也是一种数据类型,通过typeof就知道. 例子1: var CallbackFun = function(){ t ...

  8. adb命令--之查看进程及Kill进程

    adb shell kill [PID]       //杀死进程 adb 命令查看程序进程方便简洁高效 adb shell ps       //查看所有进程列表,Process Status ad ...

  9. layer获取弹出frame层数据

    通常,弹出层关闭之前,需要将部分数据传入父页面.这个时候怎么办呢? 通过success获取frame层的index. 然后通过cancel事件,获取子页面数据. 拿获取高德地图坐标为例: // 显示地 ...

  10. [JavaEE] Hibernate连接池配置测试

    转载自51CTO http://developer.51cto.com/art/200906/129914.htm Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以 ...