【Bzoj4027】兔子与樱花

本文介绍了一个关于树形结构的问题,通过树形DP和贪心策略解决节点删除问题,目的是最大化删除的节点数量,同时确保每个节点的子节点数和花朵数不超过其最大载重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

给一个n个结点的树,每个结点有最大载重m,上面有c[i]朵花,对于每个结点,它的儿子个数和花的朵数不能超过m。现在可以删掉一些结点,每删掉一个,它的花就会给父亲,求最多能删掉多少结点。


解析

树形Dp+贪心。
可以直接Dfs递归实现。
显然从权值小的开始删起。


#include <cstdio>
#include <vector>
#include <algorithm>

#define Rep( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i<=(i##_END);i++)
#define For( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i++)
#define Lop( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i>=(i##_END);i--)
#define Dnt( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i--)

using std :: min;
using std :: max;

const int maxx = 2000000 + 25;

int c[maxx];
std :: vector <int> G[maxx];
int n,m,x,y,z,ans;

bool cmp(int a,int b) {return c[a] < c[b];}

void Dfs(int x){
    For( i , 0 , G[x].size() ) Dfs(G[x][i]);
    std :: sort(G[x].begin(),G[x].end(),cmp);
    c[x] += G[x].size();
    For( i , 0 , G[x].size() ){
        int now = c[G[x][i]];
        if(c[x] + now - 1 <= m){
            c[x] += now - 1;
            ans ++;
        }
        else break;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    For( i , 0 , n ) scanf("%d",&c[i]);
    For( i , 0 , n ){
        scanf("%d",&x);
        while( x-- ){
            scanf("%d",&y);
            G[i].push_back(y);
        }
    }
    Dfs(0);
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值