BZOJ 4027: [HEOI2015]兔子与樱花 树上dp

点击打开链接

思路:树上dp,每个点的权值为d[i]+G[i].size(),然后选择最小的删除就好

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 const int maxn = 2000000+10;
 8 
 9 vector<int> G[maxn];
10 int n,m,d[maxn],ans;
11 
12 bool cmp(int x,int y){
13     return d[x]<d[y];
14 }
15 
16 void dfs(int u){
17     for(int i=0; i<G[u].size(); i++)
18         dfs(G[u][i]);
19     d[u] += G[u].size();
20     sort(G[u].begin(),G[u].end(),cmp); // 贪心 从重量小的开始拿
21     for(int i=0; i<G[u].size(); i++){
22         int v = G[u][i];
23         if(d[u]+d[v]-1<=m){
24             d[u] = d[u]+d[v]-1;
25             ans++;
26         }
27         else
28             break;
29     }
30 }
31 
32 int main(){
33     cin>>n>>m;
34     for(int i=0; i<n; i++)
35         scanf("%d",&d[i]);
36     for(int i=0; i<n; i++){
37         int num; scanf("%d",&num);
38         for(int j=0; j<num; j++){
39             int x; scanf("%d",&x);
40             G[i].push_back(x);
41         }
42     }
43     ans = 0;
44     dfs(0);
45     cout << ans << endl;
46 }
原文地址:https://www.cnblogs.com/yxg123123/p/6827728.html