【Codeforces 337D】Book of Evil 经典树形dp

题目链接:https://codeforces.ml/contest/337/problem/D

题目大意:

老题了关键在于转换.

给出一棵树与m个节点,询问有多少个点到这m个点的距离都小于等于p

题目思路:

经典做法:考虑每个点对答案的贡献

对于每个点来言,若与他距离最远的点的距离都小于等于p,那么他对答案的贡献就会+1

考虑树形dp的做法

类似求直径的做法,换根求最长链即可

s代表向下引申的最长链与次长链

t代表向上引申的最长链

这种题之前遇到过没有写博客导致思路还卡了一会儿,这次长记性先写下来

Code:

/*** keep hungry and calm CoolGuang!***/
#include 
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
ll s[maxn][2],t[maxn];
int vis[maxn];
vectorv[maxn];
int f[maxn];
void dfs1(int u,int fa){
    if(vis[u]) s[u][0] = 0;
    f[u] = fa;
    for(int e:v[u]){
        if(e == fa) continue;
        dfs1(e,u);
        if(s[u][0]p?0:1;
    }
    printf("%lld\n",ans);
    return 0;
}
/**
5 2 2
1 5
1 2
2 3
3 4
4 5
**/

 

你可能感兴趣的:(树形dp)