Question
Given a tree rooted in \ (1 \), you can choose to jump to a leaf node each time, and then jump to the ancestor whose depth is not greater than \ (k. Query the maximum number of leaf nodes that can be jumped.
\ (N, k \ Leq 10 ^ 6 \).
Analysis
The final decision must be to jump a lot of leaves and then go back to \ (U \) and then jump down.
It is found that if you can jump into the \ (U \) subtree and then jump back \ (U \), it depends on the shortest leaf and \ (U \) is the distance between \ (\ Leq k \).
Note \ (f_u \) indicates the maximum benefit of the subtree with \ (U \) as the root, \ (g_u \) indicates that the maximum benefit of \ (U \) is returned after the jump, \ ({Len} _ u \) indicates the shortest distance from \ (U \) to \ (U.
For \ (U \), if \ ({Len} _ v + 1> K \), you cannot jump to the \ (V \) subtree and return, set \ (g_v = 0 \).
To select a subtree that does not jump out after jumping in, because you cannot consider \ (g_v \) contribution, so find the largest subtree \ (f_v-g_v.
The total time complexity is \ (O (n )\).
Code
#include<bits/stdc++.h>using namespace std;#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)#define rep(i,a,b) for(int i=a;i<=b;++i)#define pb push_backtypedef long long LL;inline int gi(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();} return x*f;}template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}const int N=1e6 + 7,inf=0x3f3f3f3f;int n,edc,K;int head[N],len[N],f[N],g[N];struct edge { int last,to; edge() {} edge(int last,int to):last(last),to(to) {}} e[N*2];void Add(int a,int b) { e[++edc]=edge(head[a],b),head[a]=edc; e[++edc]=edge(head[b],a),head[b]=edc;}void dfs(int u,int fa) { len[u]=inf; int fg=1; go(u)if(v^fa){ fg=0;dfs(v,u); Min(len[u],len[v]+1); if(len[v]+1>K) g[v]=0; g[u]+=g[v]; Max(f[u],f[v]-g[v]); } if(fg) len[u]=0,g[u]=f[u]=1; else f[u]+=g[u];}int main() { n=gi(),K=gi(); rep(i,2,n) Add(i,gi()); dfs(1,0); printf("%d\n",f[1]); return 0;}
[Cf1065f] Up and down the tree [tree DP]