1. 程式人生 > >Codeforces1065F Up and Down the Tree 【樹形DP】

Codeforces1065F Up and Down the Tree 【樹形DP】

mes style clas dfs 可能 是個 con force void

推薦一道聯賽練習題。

題目分析:

你考慮進入一個子樹就可能上不來了,如果上得來的話就把能上來的全撿完然後走一個上不來的,所以這就是個基本的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 }

Codeforces1065F Up and Down the Tree 【樹形DP】