Wannafly27 C 藍魔法師 樹形DP
阿新 • • 發佈:2018-12-17
給定一棵樹,刪除一些邊,使每個連通塊不超過k個節點
表示第i個節點的子樹對其父節點提供j個連通量的方案數
#include<bits/stdc++.h> using namespace std; const int MAX=2e3+5; const int MOD=998244353; int n,K; struct P { int to,nxt; }e[MAX<<1]; int head[MAX],sz[MAX],tot,dp[MAX][MAX],tmp[MAX]; void init() { memset(head,-1,sizeof(head)); tot=0; } void adde(int u,int v) { e[tot].to=v; e[tot].nxt=head[u]; head[u]=tot++; } int add(int x,int y){return (x+=y)>=MOD?x-MOD:x;} int sub(int x,int y){return (x-=y)<0?x+MOD:x;} int mul(int x,int y){return 1ll*x*y%MOD;} void dfs(int u,int fa) { sz[u]=dp[u][1]=1; for(int i=head[u];~i;i=e[i].nxt) { int to=e[i].to; if(to==fa) continue; dfs(to,u); for(int i=0;i<=K;++i) tmp[i]=dp[u][i],dp[u][i]=0; for(int i=1;i<=sz[to];++i) dp[to][0]=add(dp[to][0],dp[to][i]); for(int i=0;i<=min(sz[to],K);++i) for(int j=1;j<=min(sz[u],K);++j)if(i+j<=K) dp[u][i+j]=add(dp[u][i+j],mul(tmp[j],dp[to][i])); sz[u]+=sz[to]; } } int main() { int x,y; while(~scanf("%d%d",&n,&K)) { init(); for(int i=1;i<n;++i) { scanf("%d%d",&x,&y); adde(x,y);adde(y,x); } dfs(1,0); int ans=0; for(int i=0;i<=K;++i) ans=add(ans,dp[1][i]); printf("%d\n",ans); } return 0; }