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;
}

  

posted @ 2018-11-05 20:14  ~Silent  阅读(176)  评论(0编辑  收藏  举报
Live2D