Codeforces1065F Up and Down the Tree 【树形DP】

推荐一道联赛练习题。

题目分析:

你考虑进入一个子树就可能上不来了,如果上得来的话就把能上来的全捡完然后走一个上不来的,所以这就是个基本的DP套路。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1002000;
 5 
 6 int n,k,fa[maxn];
 7 vector <int> g[maxn];
 8 
 9 int dep[maxn],minn[maxn];
10 
11 int f[maxn],d[maxn];
12 
13 void read(){
14     scanf("%d%d",&n,&k);
15     for(int i=2;i<=n;i++) {scanf("%d",&fa[i]);g[fa[i]].push_back(i);}
16 }
17 
18 void dfs(int now,int dp){
19     dep[now] = dp;
20     if(g[now].size() == 0){minn[now] = dp; return;}
21     minn[now] = 1e8;
22     for(int i=0;i<g[now].size();i++){
23     dfs(g[now][i],dp+1);
24     minn[now] = min(minn[now],minn[g[now][i]]);
25     }
26 }
27 
28 void dfs2(int now){
29     if(g[now].size() == 0){
30     f[now] = d[now] = 1;
31     return;
32     }
33     for(int i=0;i<g[now].size();i++) dfs2(g[now][i]);
34     for(int i=0;i<g[now].size();i++)
35     if(minn[g[now][i]] - dep[now] <= k) d[now] += d[g[now][i]];
36     for(int i=0;i<g[now].size();i++){
37     if(minn[g[now][i]] - dep[now] <= k)
38         f[now] = max(f[now],d[now]-d[g[now][i]]+f[g[now][i]]);
39     else f[now] = max(f[now],d[now]+f[g[now][i]]);
40     }
41 }
42 
43 void work(){
44     dfs(1,1);
45     dfs2(1); // dp
46     printf("%d\n",f[1]);
47 }
48 
49 int main(){
50     read();
51     work();
52     return 0;
53 }

 

posted @ 2018-10-23 11:19  menhera  阅读(377)  评论(0编辑  收藏  举报