bzoj4027: [HEOI2015]兔子与樱花

这题以前好像是做过的。

很容易发现就是treeDP了。

然后需要一点贪心的思想,对于当前以x为根的子树,删除任意的子节点,实际上答案都是+1,所以可以排序一下,然后先删那些值小的点。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n,m;
struct node
{
    int x,y,next;
}a[4100000];int len,last[2100000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

int ans;
int d[2100000],son[2100000];
int tlen,tt[2100000];
void treedp(int x)
{
    for(int k=last[x];k;k=a[k].next)treedp(a[k].y);
    
    tlen=0;
    for(int k=last[x];k;k=a[k].next)tt[++tlen]=d[a[k].y];
    sort(tt+1,tt+tlen+1);
    
    for(int i=1;i<=tlen;i++)
    {
        if(d[x]+tt[i]-1<=m)
            d[x]=d[x]+tt[i]-1, ans++;
        else break;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    
    int x;
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&son[i]);
        for(int j=1;j<=son[i];j++)
            scanf("%d",&x), ins(i,x+1);
        d[i]+=son[i];
    }
    
    ans=0;treedp(1);
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-03-04 14:36  AKCqhzdy  阅读(156)  评论(0编辑  收藏  举报