BZOJ4027/LG4107 「HEOI2015」兔子与樱花 树形DP+贪心
2024-08-27 14:31:53
问题描述
题解
首先,我们可以直接令结点 \(x\) 的权值为 \(c[x]+son_x\) ,发现将 \(x,y\) 合并,相当于增加 \(c[x]+c[y]-1\) 的重量。
容易想到对于每个结点 \(x\) ,贪心的从小到大合并 \(c[y],y \in son(x)\) ,可以获得最大的答案。
\(\mathrm{Code}\)
#include<bits/stdc++.h>
using namespace std;
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){fh=-1;ch=getchar(); }
else fh=1;
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=fh;
}
const int maxn=2000007;
int n,m,ans;
int c[maxn];
vector<int>son[maxn];
bool comp(int x,int y){
return c[x]<c[y];
}
void dp(int x){
if(son[x].size()==0) return;
for(auto y:son[x]) dp(y);
sort(son[x].begin(),son[x].end(),comp);
c[x]+=son[x].size();
for(auto y:son[x]){
if(c[x]+c[y]-1<=m){
c[x]+=c[y]-1;
++ans;
}
else break;
}
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++) read(c[i]);
for(int i=1,k;i<=n;i++){
read(k);
for(int j=1,x;j<=k;j++){
read(x);++x;
son[i].push_back(x);
}
}
dp(1);
printf("%d\n",ans);
return 0;
}
最新文章
- 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习";模板方法模式";(Template Method Pattern)
- Linux 进程与线程五
- Ubuntu 树莓派2b交叉编译环境
- Ionic2学习笔记(10):扫描二维码
- python 04
- JAVA代理模式与动态代理模式
- 标准W3C盒子模型和IE盒子模型
- Failed to create the part&#39;s controls [eclipse]
- CSS基础汇总
- 第三百二十五天 how can I 坚持
- Comparing Your Heros拓扑序列的数量
- 第一章 工欲善其事 必先利其器—Android SDK工具(3)
- Python 使用for代替in判断一个元素属于某个集合
- Android的动画
- Oracle聚合求和和聚合求积(顺便解决BOM展开的问题)
- hdu 4033 Regular Polygon 计算几何 二分+余弦定理
- 三步快速解决dll冲突问题
- [BZOJ4034] [HAOI2015] T2 (树链剖分)
- Python:正则表达式 re 模块
- 在过去五分钟内,TypeScript语言服务以外终止了5次