HEOI2015 兔子与樱花

Time Limit: 10 Sec Memory Limit: 256 MB

Description

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

现在兔子们觉得樱花树上节点太多,希望去掉一些节点。当一个节点被去掉之后,这个节点上的樱花和它的儿子节点都被连到删掉节点的父节点上。如果父节点也被删除,那么就会继续向上连接,直到第一个没有被删除的节点为止。

现在兔子们希望计算在不违背最大载重的情况下,最多能删除多少节点。

注意根节点不能被删除,被删除的节点不被计入载重。

Input

第一行输入两个正整数,\(n\)和\(m\)分别表示节点个数和最大载重

第二行\(n\)个整数\(c_i\),表示第\(i\)个节点上的樱花个数

接下来\(n\)行,每行第一个数\(k_i\)表示这个节点的儿子个数,接下来\(k_i\)个整数表示这个节点儿子的编号

Output

一行一个整数,表示最多能删除多少节点。

Sample Input

10 4
0 2 2 2 4 1 0 4 1 1
3 6 2 3
1 9
1 8
1 1
0
0
2 7 4
0
1 5
0

Sample Output

4

HINT

对于\(100\%\)的数据,\(1 \leq n \leq 2000000\), \(1 \leq m \leq 100000\), \(0 \leq c_i \leq 1000\)

数据保证初始时,每个节点樱花数与儿子节点个数之和大于\(0\)且不超过\(m\)

Solution

我们的重量显然就是樱花数+子节点数。

我们现在要尽量删最多的点。

对于一个点\(x\),它的所有子节点内能删多少点显然与\(x\)无关。那么我们现在也就只关心它的每个子节点能不能删。

于是我们可以搞出来一个新数组\(c[i]\)表示当\(i\)这个点取了最多的点时候的重量。

然后我们现在把所有子节点都按照\(c\)值从小到大排序,优先选择比较小的点删除。为什么是对的呢?可以这样考虑吧,如果有一个重量比较大的点没有选,那么事实上我们只会损失掉那个子节点的1个贡献。但是,如果我们选了重量比较小的,有可能会使得整个这个子树的根节点在其父亲那里选不了(这是也只会损失1个贡献),更有可能会使得在其父亲那里可以选(那么就很好什么贡献都不会损失),因此优先选择小的肯定不会差。

所以我们现在就是采取优先选择\(c\)值小的点的策略,一定可以得到最优解。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define REP(i,a,n) for(register int i=(a);i<=(n);++i)
#define PER(i,a,n) for(register int i=(a);i>=(n);--i)
#define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
namespace io{
    const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;
    #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    inline int getc(){return gc();}
    inline void putc(char x){*oS++=x;if(oS==oT)flush();}
    template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}
    template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}
    inline void print(const char *s){while(*s!='\0')putc(*s++);}
    inline void scan(char *s){for(c=gc();c<=' ';c=gc());for(;c>' ';c=gc())*(s++)=c;*s='\0';}
    struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}//orz laofudasuan
using io::read;using io::putc;using io::write;using io::print;
typedef long long ll;typedef unsigned long long ull;
template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;}
template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;}

const int N=2000000+7;
int n,m,x,y,c[N],ans;
vector<int>g[N];

inline char cmp(const int&x,const int&y){return c[x]<c[y];}
inline void DFS(int x){
    int len=g[x].size(),&cnt=c[x];
    for(register int i=0;i<len;++i)DFS(g[x][i]);
    sort(g[x].begin(),g[x].end(),cmp);
    for(register int i=0;i<len;++i)if(cnt+c[g[x][i]]-1<=m){cnt+=c[g[x][i]]-1;++ans;}else break;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("BZOJ4027.in","r",stdin);freopen("BZOJ4027.out","w",stdout);
#endif
    read(n),read(m);
    for(register int i=1;i<=n;++i)read(c[i]);
    for(register int i=1;i<=n;++i){
        read(x);c[i]+=x;
        for(register int j=1;j<=x;++j)read(y),g[i].push_back(y+1);
    }
    DFS(1);write(ans),putc('\n');
}

原文地址:https://www.cnblogs.com/hankeke/p/BZOJ4027.html

时间: 2024-09-30 19:23:34

HEOI2015 兔子与樱花的相关文章

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]兔子与樱花 贪心

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

[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]

[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的儿子的个数,

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为叶子节点

[luogu4107 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的儿子

BZOJ 4027 HEOI2015 兔子与樱花 树形贪心

题目大意:给定一棵有根树,每个点上有一些樱花,现在要求删除一些节点,删除节点的樱花和子节点都会连到父节点上,要求每个节点的樱花数+子节点数不超过m,求最多删多少个节点 这数据范围也只能贪心了吧= = 令fi为以节点i为根的子树中能删除的最多节点(i节点不删),gi为删除最多节点的情况下i号节点的最小负重 那么首先对于每个节点我们对于所有的子节点为根的子树尽量删,然后考虑如何删除子节点 对于节点x以及x的子节点y,若删除y节点,对gx的贡献为gy?1 因此我们对x节点的所有子节点按gy?1排序,从

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的

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,...,点