#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. TCP/IP详解学习笔记(10)-TCP连接的建立与中止

    TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接.这和前面讲到的协议完全不同.前面讲的所有协议都只是发送数据而已,大多数都不关心发送的数据是不是送到,UDP尤其明显,从编 ...

  2. Android-判断当前网络是否可用

    1.声明权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 2. ...

  3. Android中利用画图类和线程画出闪烁的心形

                                                        本文讲解主要涉及的知识点: 1.线程控制 2.画图类 3.心形函数 大家先看图片: <ig ...

  4. Android之布局属性

    1) 布局的相关属性 ① android:layout_weight="1.0",layout_weight 用于给一个线性布局中的诸多视图重要度赋值.所有的视图都有一个layou ...

  5. 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

    以数组的方法: public static void main(String[] args) {        final int n = 10;          final int k = 1;  ...

  6. EF6 Database First (DbContext) - Change Schema at runtime

    Problem:There are two SQL databases (dev and live) with on Azure which has identical table structure ...

  7. C++ 使用Htmlcxx解析Html内容(VS编译库文件)

    1.下载Htmlcxx,http://sourceforge.net/projects/htmlcxx/ 2.解压htmlcxx-0.85.tar.gz 3.打开htmlcxx.vcproj,注意是h ...

  8. 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree

    // 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree // 题意:n个点的树,每个节点有权值为正,只能用一次,每条边有负权,可以 ...

  9. [Hive - LanguageManual ] Windowing and Analytics Functions (待)

    LanguageManual WindowingAndAnalytics     Skip to end of metadata   Added by Lefty Leverenz, last edi ...

  10. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇:简介及目录》(附上完整工程文件)

    跑酷游戏制作 游戏类型: 此游戏Demo,为跑酷类游戏. 框架简介: 游戏通常由程序代码和资源组成.如果说模型.贴图.声音之类的可以给游戏环境提供一个物理描述和设置,那么脚本和代码块会给游戏赋予生命, ...