Fork me on GitHub

「HEOI2015」兔子与樱花 贪心+树形dp

Links there:HEOI2015 兔子与樱花

题意

给出一个有根树,每个节点有一个权值(樱花个数) $c_i$ ,给出定值 $m$ ,定义删除节点操作.

当一个节点被去掉之后,这个节点上的樱花和它的儿子节点都被连到删掉节点的父节点上.如果父节点也被删除,那么就会继续向上连接,直到第一个没有被删除的节点为止。

对于每一个节点 $i​$ ,它的儿子节点的个数和 $i​$ 节点上樱花个数之和不能超过 $m​$ ,$son_i + c_i \leq m​$.

求最多删去节点的个数.

思路

(感觉整天傻逼题写半天好颓废啊)

可以把树上每个点的权值看为$c_i + son_i$

每次先统计子树信息,对子树贪心从权值小的开始选并删除,直到无法使得$son_i + c_i \leq m$为止.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//my vegetable has exploded. :(
#include<bits/stdc++.h>
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
#define MM(x,y) memset(x,y,sizeof(x))
#define MCPY(a,b) memcpy(a,b,sizeof(b))
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define fi first
#define se second
#define int long long
using namespace std;

inline int quickpow(int m,int n,int p){int b=1;while(n){if(n&1)b=b*m%p;n=n>>1;m=m*m%p;}return b;}
inline int getinv(int x,int p){return quickpow(x,p-2,p);}
inline int read(void){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){f=ch=='-'?-1:1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x * f;
}
const int MAXN = 2e6+10;
vector<int>lt[MAXN];
int n,m,a[MAXN],fa[MAXN],vis[MAXN],ans;
///------------------head------------------
inline bool cmp(const int &x,const int &y){
return a[x] < a[y];
}
void dfs(int u){
for (int i = 0; i < (int)(lt[u].size()); i++) dfs(lt[u][i]);
a[u] += lt[u].size();
sort(lt[u].begin(),lt[u].end(),cmp);
for (int i = 0,v; i < (int)(lt[u].size()); i++) {
v = lt[u][i];
if (a[u] + a[v] <= m+1) ++ans,a[u] += a[v] - 1;
else break;
}
}

signed main(signed argc, char *argv[]){
n=read(),m=read();
rep(i,0,n-1) a[i]=read();
rep(i,0,n-1) {
int k=read();
while(k--){
int v=read();
fa[v]=i; lt[i].pb(v);
}
}
dfs(0);
printf("%lld\n",ans);
return 0;
}

/* Examples: */
/*
10 4
0 2 2 2 4 1 0 4 1 1
3 6 2 3
1 9
1 8
1 1
0
0
2 7 4
0
1 5
0
*/

/*
4
*/