zoukankan      html  css  js  c++  java
  • BZOJ4027: [HEOI2015]兔子与樱花 (树形DP)

    题意:一颗有根有向树 每个点有权值 定义每个节点的权值加上与他直接相连的儿子的个数不能超过m个

       可以删除一个点 使得这个点的权值赋给他父亲 把他的儿子也都连在他的父亲上

       问在满足定义的情况下最多能删除多少点

    题解:其实就有点递归+贪心的思想

       每个点的总价值为点权+儿子数

       对于每个点如果他有儿子和孙子 且删了他的孙子后 他的儿子不能删了的话

       显然是删除他的孙子比较优 虽然对答案的贡献都是1

       但是这个点的权值会小 因为没有删他儿子所传递过来的点权

       所以可以贪心的从叶子节点如果能删就删

       同样 对于同一个节点的多个儿子 dfs下去回溯时儿子已经处理好了

       显然是在不超过m的情况下对于总价值越小的儿子优先删

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int n, m;
    int q[2000005];
    int son[2000005];
    int head[2000005];
    
    struct node
    {
        int to, nex;
    }E[2000005];
    
    struct no
    {
        int id, val;
    }que[2000005];
    int ans;
    
    bool cmp(no A, no B)
    {
        return A.val < B.val;
    }
    
    void dfs(int x)
    {
        int cn = 0;
        int c = head[x];
        for(int i = c; i; i = E[i].nex)
        {
            int v = E[i].to;
            dfs(v);
    
            //que[++cn].id = v;             这样写肯定不对 cn变量xjb变了
            //que[cn].val = son[v] + q[v];
        }
    
        for(int i = c; i; i = E[i].nex)
        {
            int v = E[i].to;
            que[++cn].id = v;
            que[cn].val = son[v] + q[v];
        }
        sort(que + 1, que + 1 + cn, cmp);
    
    
        for(int i = 1; i <= cn; i++)
        {
            if(que[i].val + son[x] + q[x] - 1 <= m)
            {
                ans++;
                son[x] += son[que[i].id] - 1;
                q[x] += q[que[i].id];
            }
            else break;
        }
        return;
    }
    
    int main()
    {
        int cnt = 0;
        ans = 0;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++) scanf("%d", &q[i]);
        for(int i = 0; i < n; i++)
        {
            int x, y;
            scanf("%d", &x); son[i] = x;
            for(int j = 1; j <= x; j++)
            {
                scanf("%d", &y);
                E[++cnt].to = y; E[cnt].nex = head[i]; head[i] = cnt;
            }
        }
        dfs(0);
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    052-14
    052-13
    css垂直居中
    js中的null 和undefined
    给数组添加属性
    js中避免函数名和变量名跟别人冲突
    js变量问题
    Life
    BFC和haslayout
    json文件
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9022490.html
Copyright © 2011-2022 走看看