BZOJ 5314: [Jsoi2018]潜入行动
树形DP
#include<cstdio>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
int cnt,n,k,F[100005][105][2][2],last[100005],sz[100005],G[105][2][2];
struct node{
int to,next;
}e[200005];
void add(int a,int b){
e[++cnt].to=b;
e[cnt].next=last[a];
last[a]=cnt;
}
void dfs(int x,int fa){
sz[x]=1;
F[x][0][0][0]=1,F[x][1][1][0]=1;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (V==fa) continue;
dfs(V,x);
for (int now=0; now<=min(sz[x],k); now++){
G[now][0][0]=F[x][now][0][0],F[x][now][0][0]=0;
G[now][0][1]=F[x][now][0][1],F[x][now][0][1]=0;
G[now][1][0]=F[x][now][1][0],F[x][now][1][0]=0;
G[now][1][1]=F[x][now][1][1],F[x][now][1][1]=0;
}
for (int pre=0; pre<=min(sz[x],k); pre++)
for (int now=0; now<=min(sz[V],k-pre); now++){
int To=pre+now;
F[x][To][0][0]+=1ll*G[pre][0][0]*F[V][now][0][1]%mod; if (F[x][To][0][0]>mod) F[x][To][0][0]-=mod;
F[x][To][0][1]+=1ll*G[pre][0][0]*F[V][now][1][1]%mod; if (F[x][To][0][1]>mod) F[x][To][0][1]-=mod;
F[x][To][0][1]+=1ll*G[pre][0][1]*(F[V][now][0][1]+F[V][now][1][1])%mod; if (F[x][To][0][1]>mod) F[x][To][0][1]-=mod;
F[x][To][1][0]+=1ll*G[pre][1][0]*(F[V][now][0][0]+F[V][now][0][1])%mod; if (F[x][To][1][0]>mod) F[x][To][1][0]-=mod;
F[x][To][1][1]+=1ll*G[pre][1][0]*(F[V][now][1][0]+F[V][now][1][1])%mod; if (F[x][To][1][1]>mod) F[x][To][1][1]-=mod;
F[x][To][1][1]+=1ll*G[pre][1][1]*(1ll*F[V][now][0][0]+F[V][now][0][1]+F[V][now][1][0]+F[V][now][1][1])%mod;
if (F[x][To][1][1]>mod) F[x][To][1][1]-=mod;
}
sz[x]+=sz[V];
}
}
int main(){
scanf("%d%d",&n,&k);
for (int i=1; i<n; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
printf("%d\n",(F[1][k][0][1]+F[1][k][1][1])%mod);
return 0;
}

浙公网安备 33010602011771号