P4516 [JSOI2018] 潜入行动

/*
一棵树 每个点放置监听器 只能染色 距离==1的点 但不能染色自己
问 有多少种方式可以 监听整棵树

f[u][i][0/1][0/1] root=u 的子树 放置i个装置 --u 放1/不放0 ---u 被监视1/不监视0  
:::f[j][u][i][0/1][0/1] 前j棵子树
:::除了root 其它点一定都被监视 bec root可以通过后面的点 进行更新
f[u][i][0][0]=sum(f[u][j][0][0]*f[v][i-j][0][1])
f[u][i][0][1]=sum(f[u][j][0][1]*(f[v][i-j][0][1]+f[v][i-j][1][1])+f[u][j][0][0]*f[u][i-j][1][1])             
f[u][i][1][0]=sum(f[u][j][1][0]*(f[v][i-j][0][0]+f[v][i-j][0][1]))
f[u][i][1][1]=sum(f[u][j][1][0]*(f[v][i-j][1][0]+f[v][i-j][1][1])+f[u][j][1][1]*(f[v][i-j][0][0]+f[v][i-j][0][1]+f[v][i-j][1][0]+f[v][i-j][1][1]))                               
:::--------=>f[j][][][]=sum(f[j-1][][][]......) 所以每一层都要 mem 0 
所以状态更新很麻烦-> i+j--i---j 提前记录前一层的状态
:::ans%mod=1e9++ 所以中途肯定要exceed int
*/
/*
5 3
1 2
2 3
3 4
4 5

1

*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e5 +10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;

int n,k,head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
int dp[maxn][110][2][2],siz[maxn],tmp[110][2][2];

int solve(int x,ll y){//ll % int 会出问题 ->大数+ ->
    if(y>=mod) y%=mod;
    for(x+=y;x>=mod;x-=mod);
    return x;
}

void add(int a,int b){
    to[++tot]=b,nxt[tot]=head[a],head[a]=tot;
}

void dfs(int u,int fa)
{
    siz[u]=dp[u][1][1][0]=dp[u][0][0][0]=1;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];if(v==fa) continue;
        dfs(v,u);
        for(int j=0;j<=min(siz[u],k);j++)
        {
            tmp[j][0][0]=dp[u][j][0][0],dp[u][j][0][0]=0;
            tmp[j][0][1]=dp[u][j][0][1],dp[u][j][0][1]=0;
            tmp[j][1][0]=dp[u][j][1][0],dp[u][j][1][0]=0;
            tmp[j][1][1]=dp[u][j][1][1],dp[u][j][1][1]=0;
        }
        for(int j=min(siz[u],k);j>=0;j--)
        {
            for(int jj=min(siz[v],k-j);jj>=0;jj--)
            {
                dp[u][jj+j][0][0] = solve(dp[u][jj+j][0][0],1ll * tmp[j][0][0] * dp[v][jj][0][1]);
            
                dp[u][jj+j][0][1] = solve(dp[u][jj+j][0][1],1ll * tmp[j][0][1] * (dp[v][jj][0][1] + dp[v][jj][1][1]));
                dp[u][jj+j][0][1] = solve(dp[u][jj+j][0][1],1ll * tmp[j][0][0] * dp[v][jj][1][1]);
            
                dp[u][jj+j][1][0] = solve(dp[u][jj+j][1][0],1ll * tmp[j][1][0] * (dp[v][jj][0][0] + dp[v][jj][0][1]));
                dp[u][jj+j][1][1] = solve(dp[u][jj+j][1][1],1ll * tmp[j][1][0] * (dp[v][jj][1][0] + dp[v][jj][1][1]));
            
                dp[u][jj+j][1][1] = solve(dp[u][jj+j][1][1],1ll * tmp[j][1][1] * (1ll * dp[v][jj][0][0] + 1ll * dp[v][jj][0][1] + 1ll * dp[v][jj][1][0] + 1ll * dp[v][jj][1][1]));
            }
        }
        siz[u]+=siz[v];
    }
}
/*
void dfs(int u,int fa)
{
    siz[u] = dp[u][0][0][0] = dp[u][1][1][0] = 1;
    for (int t = head[u]; t ; t = nxt[t])
    {
        int v = to[t];
        if (v == fa) continue;
        dfs(v,u);
        int side = min(siz[u],k);
        for (int i = side; i >=0; --i)
        {
            tmp[i][0][0] = dp[u][i][0][0];
            dp[u][i][0][0] = 0;
            tmp[i][0][1] = dp[u][i][0][1];
            dp[u][i][0][1] = 0;
            tmp[i][1][0] = dp[u][i][1][0];
            dp[u][i][1][0] = 0;
            tmp[i][1][1] = dp[u][i][1][1];
            dp[u][i][1][1] = 0;
        }
        for (int i = side; i>=0; --i)
        {
            int limit = min(siz[v],k-i);
            for (int j = limit; j >=0; --j)
            {
                dp[u][i+j][0][0] = solve(dp[u][i+j][0][0],1ll * tmp[i][0][0] * dp[v][j][0][1]);
                dp[u][i+j][0][1] = solve(dp[u][i+j][0][1],1ll * tmp[i][0][1] * (dp[v][j][0][1] + dp[v][j][1][1]));
                dp[u][i+j][0][1] = solve(dp[u][i+j][0][1],1ll * tmp[i][0][0] * dp[v][j][1][1]);
                dp[u][i+j][1][0] = solve(dp[u][i+j][1][0],1ll * tmp[i][1][0] * (dp[v][j][0][0] + dp[v][j][0][1]));
                dp[u][i+j][1][1] = solve(dp[u][i+j][1][1],1ll * tmp[i][1][0] * (dp[v][j][1][0] + dp[v][j][1][1]));
                dp[u][i+j][1][1] = solve(dp[u][i+j][1][1],1ll * tmp[i][1][1] * (1ll * dp[v][j][0][0] + 1ll * dp[v][j][0][1] + 1ll * dp[v][j][1][0] + 1ll * dp[v][j][1][1]));
            }
        }
        siz[u] += siz[v];
    }
}
*/
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=n-1;i++){
        int a,b;cin>>a>>b;
        add(a,b),add(b,a);
    }
    dfs(1,0);
    cout<<(ll)(dp[1][k][1][1]+dp[1][k][0][1])%mod<<'\n';
    
    return 0;
}

 

posted @ 2023-11-13 04:00  JMXZ  阅读(10)  评论(0)    收藏  举报