[bzoj4027][HEOI2015]兔子与樱花_贪心_树形dp

兔子与樱花 bzoj-4027 HEOI-2015

题目大意:每个点有c[i]朵樱花,有一个称重m, son[i]+c[i]<=m.如果删除一个节点,这个节点的樱花或移动到它的祖先中深度最大的,且没有被删除的节点,求在满足所有点界限的情况下,最多能删除的节点数。

注释:$1\le n\le 2\cdot 10^6$,$1\le m\le 10^5$,$0\le c_i\le 1000$。

想法:开始的时候很容易想到贪心,但是这东西对不对还两说

其实仔细一想这玩意儿tm显然啊??!

我们令c[i]+son[i]为这个点的优先级,我们显然选优先级高的。

如果我们选了一个优先级略低的,比如说是最高优先级的..子孙?这样的话我只会是的上面的优先级哐哐往上涨直到不合法

祖先的话删完了之后优先级高的迟早要删,这样的话底下的樱花上来就GG了。

最后,附上丑陋的代码... ...

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int maxn=2000010,maxm=maxn<<1;
using namespace std;
int n,m,pre[maxm],now[maxn],son[maxm],tot,c[maxn],a[maxn],ans;
bool ok;char ch;
void read(int &x){
	for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
	for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
	if (ok) x=-x;
}
void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
void dfs(int x){
	for (int y=now[x];y;y=pre[y]) dfs(son[y]);
	int cnt=0;
	for (int y=now[x];y;y=pre[y]) a[++cnt]=c[son[y]];
	sort(a+1,a+1+cnt);
	for (int i=1;i<=cnt;i++){
		if (c[x]+a[i]-1>m) break;
		c[x]+=(a[i]-1),ans++;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) read(c[i]);
	for (int i=1,x,num;i<=n;i++){
		read(num),c[i]+=num;
		for (int j=1;j<=num;j++) read(x),x++,add(i,x);
	}
	dfs(1),printf("%d\n",ans);
	//for (int i=1;i<=n;i++) printf("%d %d %d\n",i,f[i],g[i]);
	return 0;
}

小结:对于这种贪心的题,我们还是需要证明一下的... ...

原文地址:https://www.cnblogs.com/ShuraK/p/9277668.html

时间: 2024-09-30 14:50:02

[bzoj4027][HEOI2015]兔子与樱花_贪心_树形dp的相关文章

dfs+贪心 BZOJ4027 [HEOI2015] 兔子与樱花

4027: [HEOI2015]兔子与樱花 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1159  Solved: 664[Submit][Status][Discuss] Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它看成一个有根树结构,其中0号节点是根节点.这个树的每个节点上

[bzoj4027][HEOI2015][兔子与樱花] (树形dp思想+玄学贪心)

Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它看成一个有根树结构,其中0号节点是根节点.这个树的每个节点上都会有一些樱花,其中第i个节点有c_i朵樱花.樱花树的每一个节点都有最大的载重m,对于每一个节点i,它的儿子节点的个数和i节点上樱花个数之和不能超过m,即son(i) + c_i <= m,其中son(i)表示i的儿子的个数,

bzoj4027: [HEOI2015]兔子与樱花 贪心

本人总觉得贪心不清真不是正解,可有的骚题他就是正解而且我还老碰上,所以说,有的时候是要感性理解一下或者证一下,贪心大佬..... 这个题看数据,dp太难,往贪心那边想一下吧..... 本题的做法是建树,从叶结点开始合并代价直到不行为止(证明:首先假设我们已经找到一个最优解但他不是从叶到根合并到死,那么对于合并的点我们可以把其中的点从低到高依次再合并他的子节点,第一层由于合并了子节点而他又是最优解所以最多合并一个子节点并把它自己释放,第二层同理....最高层因为是最优解肯定不能再合并子节点:队友不

bzoj4027[HEOI2015]兔子与樱花

http://www.lydsy.com/JudgeOnline/problem.php?id=4027 贪心. 我们发现,如果点i被删,那么它使父亲增加的重量为c[i]+son[i]-1 我们记val[i]=c[i]+son[i]-1 我们把删去的点染成灰色,发现其实这样的: 每个红色部分中,若干个被删去的点(灰色)和一个未删去的点(白色)组成了一棵树,这棵树合法当且仅当每个红色部分中val值的和小于等于M-1,即∑val<=M-1 我们可以用拟阵来证明贪心: S={点_1,点_2,...,点

BZOJ 4027:[HEOI2015]兔子与樱花(贪心+树形DP)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4027 [题目大意] 樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接, 我们可以把它看成一个有根树结构,其中0号节点是根节点. 这个树的每个节点上都会有一些樱花,其中第i个节点有c_i朵樱花. 樱花树的每一个节点都有最大的载重m,对于每一个节点i, 它的儿子节点的个数和i节点上樱花个数之和不能超过m,即son(i)+c_i<=m, 其中son(i)表示i的

&lt;bzoj4027: [HEOI2015]兔子与樱花&gt; (树形DP)

题意:一颗有根有向树 每个点有权值 定义每个节点的权值加上与他直接相连的儿子的个数不能超过m个 可以删除一个点 使得这个点的权值赋给他父亲 把他的儿子也都连在他的父亲上 问在满足定义的情况下最多能删除多少点 题解:其实就有点递归+贪心的思想 每个点的总价值为点权+儿子数 对于每个点如果他有儿子和孙子 且删了他的孙子后 他的儿子不能删了的话 显然是删除他的孙子比较优 虽然对答案的贡献都是1 但是这个点的权值会小 因为没有删他儿子所传递过来的点权 所以可以贪心的从叶子节点如果能删就删 同样 对于同一

【BZOJ4027】[HEOI2015]兔子与樱花 贪心

[BZOJ4027][HEOI2015]兔子与樱花 Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它看成一个有根树结构,其中0号节点是根节点.这个树的每个节点上都会有一些樱花,其中第i个节点有c_i朵樱花.樱花树的每一个节点都有最大的载重m,对于每一个节点i,它的儿子节点的个数和i节点上樱花个数之和不能超过m,即son(i) + c

[bzoj2097][Usaco2010 Dec]Exercise 奶牛健美操_贪心_树形dp_二分

Exercise bzoj-2097 Usaco-2010 Dec 题目大意:题目链接 注释:略. 想法:题目描述生怕你不知道这题在考二分. 关键是怎么验证?我们想到贪心的删边. 这样的策略是显然正确的. 之后树形dp的时候维护一下就行. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 10001

B20J_4027_[HEOI2015]兔子与樱花_树形DP

题意: 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它看成一个有根树结构,其中0号节点是根节点.这个树的每个节点上都会有一些樱花,其中第i个节点有c_i朵樱花.樱花树的每一个节点都有最大的载重m,对于每一个节点i,它的儿子节点的个数和i节点上樱花个数之和不能超过m,即son(i) + c_i <= m,其中son(i)表示i的儿子的个数,如果i为叶子节点