bzoj4027 HEOI2015 兔子與櫻花

2021-08-09 16:10:21 字數 1723 閱讀 9143

[submit][status][discuss]

description

很久很久之前,森林裡住著一群兔子。有一天,兔子們突然決定要去看櫻花。兔子們所在森林裡的櫻花樹很特殊。櫻花樹由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 91 8

1 12 7 4

1 50

sample output

4 hint

對於100%的資料,1 <= n <= 2000000, 1 <= m <= 100000, 0 <= c_i <= 1000

資料保證初始時,每個節點櫻花數與兒子節點個數之和大於0且不超過m

看gxz大佬部落格寫的第一題

做法顯然是貪心,考慮到乙個節點的子節點從小到大排序輪流刪除=>刪最多的子節點

如果因為刪了過多的子節點導致這個節點的父親無法刪去這個節點,那麼如果不刪這個字節點至少答案要減一,能刪這個節點最多為答案貢獻為1.所以刪去一定不會劣與不刪。

所以對每個節點,考慮將子節點按大小排序然後刪。子節點大小是什麼呢?

如果刪去乙個子節點他對他父親的貢獻是他的櫻花數,加上他的兒子的數量,再減去1(自己}。所以乙個節點的重量不妨看做櫻花數加上兒子的數量。

所以就很簡單了,一次dfs,對每個節點的孩子排序

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

int read()

const

int maxn = 2000005;

vector

son[maxn];

int a[maxn];

int n,m;

int ans;

bool cmp(int x,int y)

int main()

}dp(1);

cout

<}

bzoj4027 heoi2015 兔子與櫻花

time limit 10 sec memory limit 256 mb submit 360 solved 187 submit status discuss 很久很久之前,森林裡住著一群兔子。有一天,兔子們突然決定要去看櫻花。兔子們所在森林裡的櫻花樹很特殊。櫻花樹由n個樹枝分叉點組成,編號從0...

BZOJ4027 HEOI2015 兔子與櫻花

bzoj4027 一開始想的都是二維的dp 資料這麼大怎麼轉移啊qa q 後來發現原來貪心就行辣。直接記ans i so ni c i 那麼將這個點刪除對應著其父節點 ansi 1那麼對於某個點 x 將兒子的an s值從小到大排徐,然後依次刪直到不能刪為止。然後刪下面的比刪上面的優。因為刪某個點 x...

BZOJ4027 HEOI2015 兔子與櫻花

bzoj4027 heoi2015 兔子與櫻花 很久很久之前,森林裡住著一群兔子。有一天,兔子們突然決定要去看櫻花。兔子們所在森林裡的櫻花樹很特殊。櫻花樹由n個樹枝分叉點組成,編號從0到n 1,這n個分叉點由n 1個樹枝連線,我們可以把它看成乙個有根樹結構,其中0號節點是根節點。這個樹的每個節點上都...