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

Time Limit: 1 Sec

Memory Limit: 256 MB

题目连接

http://uoj.ac/problem/139

Description

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

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

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

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

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

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

Input

第一行一个正整数 n 表示树的节点个数。

接下来的 n−1 行,每行是两个整数 u,v (1≤u,v≤n,u≠v) 表示树上的一条边。

Output

一个整数,表示在所有合法方案中黑色节点的最多数量。

Sample Input

7
1 2
1 3
2 4
2 5
3 6
3 7

Sample Output

7

HINT

题意

题解:

首先贪心一下,对于每条从叶子到根节点的黑色棋子个数,应该是最浅的叶子节点的深度

于是我们就可以一次dfs求出这个深度,然后再染色就好了

染色我比较麻烦,我是用dfs序维护的……

每次从叶子节点往上染色,先查询一下这个点的祖先已经染了多少个点,然后再慢慢跑的

代码:

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
#define maxn 300005
vector<int> G[maxn];
vector<int> P;
int n;
struct PPP
{
int l,d,r;
}node[maxn];
struct Node
{
int lft,rht;
LL sum,add;
int mid(){return MID(lft,rht);}
void fun(LL tmp)
{
add+=tmp;
sum+=(rht-lft+)*tmp;
}
}; int y[maxn]; struct Segtree
{
Node tree[maxn*];
void relax(int ind)
{
if(tree[ind].add)
{
tree[LL(ind)].fun(tree[ind].add);
tree[RR(ind)].fun(tree[ind].add);
tree[ind].add=;
}
}
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft; tree[ind].rht=rht;
tree[ind].sum=; tree[ind].add=;
if(lft==rht) tree[ind].sum=y[lft];
else
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid+,rht,RR(ind));
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
}
}
void updata(int st,int ed,int ind,int add)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) tree[ind].fun(add);
else
{
relax(ind);
int mid=tree[ind].mid();
if(st<=mid) updata(st,ed,LL(ind),add);
if(ed> mid) updata(st,ed,RR(ind),add);
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
}
}
LL query(int st,int ed,int ind)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) return tree[ind].sum;
else
{
relax(ind);
int mid=tree[ind].mid();
LL sum1=,sum2=;
if(st<=mid) sum1=query(st,ed,LL(ind));
if(ed> mid) sum2=query(st,ed,RR(ind));
return sum1+sum2;
}
}
}seg;
int cnt = ;
int cntt = ;
int ans = ;
bool cmp(int a,int b)
{
return node[a].d<node[b].d;
}
void dfs3(int x,int fa,int d)
{
node[x].l=cntt++;
node[x].d=d;
for(int i=;i<G[x].size();i++)
{
if(G[x][i]==fa)
continue;
dfs3(G[x][i],x,d+);
}
node[x].r=cntt;
}
void dfs(int x,int pre,int add)
{
if(G[x].size()==&&x!=)
{
P.push_back(x);
ans = min(ans,add);
return;
}
for(int i=;i<G[x].size();i++)
{
int v=G[x][i];
if(v==pre)continue;
dfs(v,x,add+);
}
}
int Ans = ;
int vis[maxn];
void dfs2(int x,int pre,int add)
{ if(vis[x])return;
if(add<=)return;
vis[x]=;
Ans++;
seg.updata(node[x].l,node[x].r-,,);
for(int i=;i<G[x].size();i++)
{
int v = G[x][i];
if(v==pre)continue;
if(node[v].d >= node[x].d)continue;
dfs2(v,x,add-);
}
}
int main()
{
//freopen("k.in","r",stdin);
//freopen("2.out","w",stdout);
scanf("%d",&n);
if(n==)
{
printf("1\n");return ;
}
for(int i=;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
seg.build(,n,);
dfs(,-,);
dfs3(,-,);
sort(P.begin(),P.end(),cmp);
for(int i=;i<P.size();i++)
{ int t = ;
int xx = seg.query(node[P[i]].l,node[P[i]].l,);
if(xx<)continue;
if(P[i]!=)
t = ans-xx;
dfs2(P[i],-,t);
}
printf("%d\n",Ans);
}

uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心的更多相关文章

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

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

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

    题意: 很久很久以前,有一棵树加入了 UOJ 群. 这天,在它讨论“一棵树应该怎么旋转”的时候一不小心被删除了,变成了被删除的树. 突然间,它突然发现它失去了颜色,变成了一棵纯白的树.这让它感觉很焦躁 ...

  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. RegExp类型和text()方法

    ECMAScript通过RegExp类型来支持正则表达式 RegExp 实例方法:text() 它接受一个字符串参数,在模式与该参数匹配的情况下返回true,否则返回false,通常用在if语句中 / ...

  2. Oracle 课程八之性能优化之10053事件

    一. 10053事件 当一个SQL出现性能问题的时候,可以使用SQL_TRACE 或者 10046事件来跟踪SQL. 通过生成的trace来了解SQL的执行过程. 我们在查看一条SQL的执行计划的时候 ...

  3. python 资料

    主站: 主页:http://python.org/下载:http://python.org/download/文档:http://python.org/doc/ books: ActivePython ...

  4. STM32F407 外扩SRAM

    字节控制功能.支持高/低字节控制. 看看实现 IS62WV51216 的访问,需要对 FSMC进行哪些配置. 这里就做一个概括性的讲解.步骤如下: 1)使能 FSMC 时钟,并配置 FSMC 相关的  ...

  5. CodeForce---Educational Codeforces Round 3 D. Gadgets for dollars and pounds 正题

    对于这题笔者无解,只有手抄一份正解过来了: 基本思想就是 : 二分答案,对于第x天,计算它最少的花费f(x),<=s就是可行的,这是一个单调的函数,所以可以二分. 对于f(x)的计算,我用了nl ...

  6. javascript跑马灯抽奖

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. python中List的sort方法的用法

    python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...

  8. 微信公众平台开发(57)Emoji表情符号

    微信公众平台开发 微信公众平台开发模式 企业微信公众平台 Emoji表情符号 作者:方倍工作室 地址:http://www.cnblogs.com/txw1958/p/crack-golden-egg ...

  9. bzoj 3675 [Apio2014]序列分割(斜率DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3675 [题意] 将n个数的序列分割k次,每次的利益为分割后两部分数值和的积,求最大利益 ...

  10. C#调用dll(C++(Win32))时的类型转换总结(转)

    http://www.cnblogs.com/lidabo/archive/2012/06/05/2536737.html     C++(Win 32) C# char** 作为输入参数转为char ...