经典树上DP
注意优化:边dfs边算!!
我认为相当于两次dp
一次是节点,一次是节点的各条边
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 5005
using namespace std;
const int M=786433;
long long f[N][N],K,n,m;
long long head[N],ver[N<<1],nex[N<<1],tot,size[N],cnt[N],g[N];
inline void add(int x,int y){
nex[++tot]=head[x];
head[x]=tot;ver[tot]=y;
}
void dfs(int x,int fa){
size[x]++;f[x][1]=1;cnt[x]=0;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(y==fa)continue;
dfs(y,x);
for(int j=1;j<=size[x]+size[y];j++)g[j]=0;
for(int j=1;j<=size[x];j++)g[j]=(cnt[y]*f[x][j])%M;
for(int j=1;j<=size[x];j++){
for(int k=1;k<=size[y];k++){
g[j+k]=(g[j+k]+(f[x][j]*f[y][k])%M)%M;
}
}
for(int j=1;j<=size[x]+size[y];j++)f[x][j]=g[j];
size[x]+=size[y];
}
for(int i=K;i<=size[x];i++)cnt[x]=(cnt[x]+f[x][i])%M;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>K;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);add(y,x);
}
dfs(1,1);
cout<<cnt[1]<<endl;
return 0;
}