B20J 4027 HEOI2015 兔子與櫻花

2022-04-30 05:57:11 字數 1269 閱讀 7150

b20j_4027_[heoi2015]兔子與櫻花_樹形dp

題意:

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

現在兔子們覺得櫻花樹上節點太多,希望去掉一些節點。當乙個節點被去掉之後,這個節點上的櫻花和它的兒子節點都被連到刪掉節點的父節點上。如果父節點也被刪除,那麼就會繼續向上連線,直到第乙個沒有被刪除的節點為止。

現在兔子們希望計算在不違背最大載重的情況下,最多能刪除多少節點。

注意根節點不能被刪除,被刪除的節點不被計入載重。

分析:

我們仔細思考一下就會發現從下往上刪不會使答案變差,並且刪兒子不會對父親的祖先產生影響。

對於每個結點,貪心的取兒子中貢獻小的,並加入到自身的貢獻

乙個點的貢獻 = 兒子的個數 + 這個點的權值

**:

#include #include #include using namespace std;

#define n 2000050

int head[n],to[n<<1],nxt[n<<1],cnt;

int n,m,c[n],son[n],a[n],tot,b[n],ans,nm[n];

inline void add(int u,int v)

void read(int &x)

while(s>='0'&&s<='9')

x*=f;

}void dfs(int x,int y)

}int cnt=0;

for(int i=head[x];i;i=nxt[i])

}sort(b+1,b+cnt+1);

c[x]+=son[x];

for(int i=1;i<=cnt;i++)else break;

}}int main()

int x,y;

for(int i=1;i<=n;i++)

}dfs(1,0);

printf("%d",ans);

}

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 兔子與櫻花

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