题目

不难发现有一个暴力\(dp\)

设\(dp[x][l]\)表示\(x\)点子树内所有叶子节点到\(x\)的路径上都有\(l\)和黑点时最多能染多个黑点

转移就是

\[dp[x][l]=\max(\sum_{v\in son(x)}dp[v][l],1+\sum_{v\in son(x)}dp[v][l-1])
\]

转移是\(O(n^2)\)的,复杂度跟深度有关,或许可以长剖但是不会

瞎猜一波不难发现最优情况下,深度最小的叶子节点到根的路径上肯定是都染成黑色了,即所有叶子节点到根的路径上的黑色节点个数都等于深度最小的叶子节点的深度,设这个最小叶子节点深度为\(k\)

而一个点染成黑色,那么这个点子树里所有叶子节点都会产生影响,我们要尽量多得将节点染黑,那么就需要让黑色节点的深度尽量大

我们将所有叶子节点按照深度排序,先将深度最小的叶子节点到根的路径染成黑色,同时维护\(res[x]\)表示\(x\)节点到根的路径上一共染了多少个黑点

接下来一次处理所有叶子节点,暴力往上跳即可,直到跳到一个节点\(x\)有\(res[x]!=0\)

那么就说明从这个叶子节点到\(x\)的路径上还需要染上\(k-res[x]\)个黑点,我们贪心地染\(k-res[x]\)个深度较大的节点就好了

复杂度的瓶颈在于排序

代码

#include<bits/stdc++.h>
#define re register
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=1e5+5;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt;}e[maxn<<1];
int n,num,head[maxn],fa[maxn],res[maxn],lve[maxn],deep[maxn],ans,tot;
inline int cmp(int A,int B) {return deep[A]<deep[B];}
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
void dfs(int x) {
int flag=0;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
flag|=1;deep[e[i].v]=deep[x]+1;
dfs(e[i].v);fa[e[i].v]=x;
}
if(!flag) lve[++tot]=x;
}
int main() {
n=read();
for(re int y,x,i=1;i<n;i++)
x=read(),y=read(),add(x,y),add(y,x);
deep[1]=1;dfs(1);
std::sort(lve+1,lve+tot+1,cmp);
int x=lve[1];
while(x) res[x]=deep[x],x=fa[x],++ans;
for(re int i=2;i<=tot;i++) {
int x=lve[i];
while(x&&!res[fa[x]]) x=fa[x];
int k=deep[lve[1]]-res[fa[x]];
x=lve[i];int now=0;
while(x&&!res[x]) {
if(now<k) ++ans,res[x]=deep[lve[1]]-now;
else res[x]=deep[lve[1]]-k;
x=fa[x];++now;
}
}
printf("%d\n",ans);
return 0;
}

最新文章

  1. jquery获取table的行数、列数
  2. JSP连接数据库,报Unable to compile class for JSP
  3. html中的rel,rev是什么?
  4. 用nodejs搭建一个简单的服务器
  5. EBS R12.2应用层关闭脚本的执行过程
  6. 20145215《Java程序设计》第10周学习总结
  7. java 面向对象编程 第18章——网络编程
  8. flask-admin
  9. ActionBar功能,效果图一览
  10. 第二章_session管理
  11. PHP时间戳与时间相互转换(精确到毫秒)
  12. ASP.NET 运行机制详解
  13. WPF DataTriger 用法示例代码
  14. bootstrap学习地址2017.6.1
  15. TPS,并发用户数,吞吐量以及一些计算公式
  16. JavaBean+Servlet 开发时,JavaBean 编写问题
  17. JAVA内部类小结
  18. 019 mapreduce的核心--shuffle理解,以及在shuffle中的优化
  19. Mysql双主 keepalived+lvs实现mysql高可用性
  20. python学习笔记(二十九)为什么python的多线程不能利用多核CPU

热门文章

  1. C++——变量
  2. JAVA FileUtils(文件读写以及操作工具类)
  3. mkdir无法创建目录权限不够
  4. PhotoShop的10大误区
  5. &lt;随便写&gt;软件设计遵循的基本原则
  6. 十分钟学习 react配套的类型检测库——prop-types的运用
  7. 从零开始搭建系统2.2——ELK安装及配置
  8. 构建单页Web应用——简单概述
  9. 欧拉定理、欧拉函数、a/b%c
  10. Perl 循环