outline
給一棵樹,編號為0~n-1,樹有承重值m,每個節點的承重為自身價值c[i]加上其孩子個數son[i]。 這不科學啊,不應該是整個子樹的價值嗎? 每刪乙個節點,就將其孩子連向其父親,自己的價值加進其父親的價值中,並保證滿足承重要求(承重不超過m)。求其節點最多能刪幾個?input
第一行輸入兩個正整數,noutputnn和 m
mm 分別表示節點個數和最大載重
第二行 n
nn 個整數 c
ic_i
ci ,表示第 i
ii 個節點上的櫻花個數
接下來 n
nn 行,每行第乙個數 k
ik_i
ki 表示這個節點的兒子個數,接下來 k
ik_i
ki 個整數表示這個節點兒子的編號
一行乙個整數,表示最多能刪除多少節點thinking
刪節點肯定要有順序,如果從上面開始刪的話,那會使各節點的值都加進根節點,根節點根本就吃不消,這不會優;所以反過來,就從葉子節點開始刪。但有好多乙個節點有好多子節點,要刪哪個?那麼便會考慮子節點間的不同之處,會發現,若先把承重值小的點先上去的話,便還有可能刪去其他點;反之則不能。因為要為子節點排序,所以不應該用子節點找父親,而應該用父節點找孩子,找完孩子中最小的。以此類推,便想到了深搜code
#include
#define maxn 2123456
using
namespace std;
int n,m,ans,c[maxn]
;vector<
int> vec[maxn]
;bool
cmp(
int a,
int b)
void
dfs(
int x)
}int
main()
dfs(0)
;printf
("%d"
,ans)
;return0;
}
貪心 A 兔子與櫻花
兔子與櫻花原題 需要求出最大的可以刪除的節點的數量。我們從葉子節點開始刪。為什麼不從別的節點開始呢?假設我們不從葉子節點開始,那麼每一次的刪除都需要考慮節點的父節點的權重與該節點的權重和子節點的數量,而如果我們從葉子節點開始,只需要考慮節點的權重與其父節點的權重即可。相對而言比較簡單。要刪除的葉子節...
Bzoj4027 兔子與櫻花
給乙個n個結點的樹,每個結點有最大載重m,上面有c i 朵花,對於每個結點,它的兒子個數和花的朵數不能超過m。現在可以刪掉一些結點,每刪掉乙個,它的花就會給父親,求最多能刪掉多少結點。樹形dp 貪心。可以直接dfs遞迴實現。顯然從權值小的開始刪起。include include include de...
bzoj4027 兔子與櫻花
看來該去惡補一下貪心了 對於某乙個節點來說,可以發現從小到 擇它的兒子的cost是最優的 因為要選盡量多的節點 那麼就可以去遞迴搞了,然後排個序就行。1 include 2 include 3 include 4 include 5 include 6 include 7 include 8 inc...