• [HEOI2015]兔子与樱花


    zz:https://www.cnblogs.com/fengzhiyuan/p/8119415.html

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

    Source
    题解:
    树形贪心。对于任意一个节点,它当前的权值为c[i]+son[i]。
    假设我们删除了它的某一个儿子节点j,则权值增加c[j]+son[j]-1。
    那么显然,我们在删除节点的时候,应该从权值最小的到最大的依次进行,直到当前节点的权值已经超过限重。

    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    
    #define N 2000007
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m,ans;
    int c[N];
    vector<int>e[N];
    
    bool cmp(int a,int b){return c[a]<c[b];}
    void dfs(int x)
    {
        for(int i=0;i<e[x].size();i++)
            dfs(e[x][i]);
        sort(e[x].begin(),e[x].end(),cmp);
        c[x]+=e[x].size();
        for(int i=0;i<e[x].size();i++)
        {
            int t=c[e[x][i]];
            if(c[x]+t-1<=m)
            {
                c[x]+=t-1;
                ans++;
            }
        }        
    }
    int main()
    {
        n=read();m=read();
        for(int i=0;i<n;i++)
            c[i]=read();
        for(int i=0,x,y;i<n;i++)
        {
            x=read();
            while(x--)
            {
                y=read();
                e[i].push_back(y);
            }
        }
        dfs(0),printf("%d\n",ans);
    }
  • 相关阅读:
    Vue 2.x windows环境下安装
    VSCODE官网下载缓慢或下载失败 解决办法
    angular cli 降级
    Win10 VS2019 设置 以管理员身份运行
    XSHELL 连接 阿里云ECS实例
    Chrome浏览器跨域设置
    DBeaver 执行 mysql 多条语句报错
    DBeaver 连接MySql 8.0 报错 Public Key Retrieval is not allowed
    DBeaver 连接MySql 8.0报错 Unable to load authentication plugin 'caching_sha2_password'
    Linux系统分区
  • 原文地址:https://www.cnblogs.com/cutemush/p/11694364.html
Copyright © 2020-2023  润新知