CF855CHelga Hufflepuff's Cup题解

根据题意,我们可以发现这是一道树形 dp。首先考虑设计状态,注意到 k 较小,那么我们可以在 dp 数组里面塞一维来维护特殊颜色点的个数。然后题目里有颜色编号的大小限制,所以第三维用 0/1/2 来分别表示当前颜色小于/等于/大于 k 的情况。那么这样的话就是用 fi,j,0/1/2 表示在以 i 为根的子树内,有 j 个特殊颜色在三种情况下的答案。那么转移方程式即为:

fx,i+j,0=ysonxfx,i,0×(fy,j,0+fy,j,1+fy,j,2)

fx,i+j,1=ysonxfx,i,1×fy,j,0

fx,i+j,2=ysonxfx,i,2×(fy,j,0+fy,j,2)

树形背包转移即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int mod=1e9+7;
const int N=1e5+10;
inline int read(){
    int f=1,w=0;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')  f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        w=(w<<1)+(w<<3)+(c^48);
        c=getchar();
    }
    return f*w;
}
struct node{
    int to,nex;
}e[N*2];
int head[N],tot;
void add_edge(int x,int y){
    e[++tot].to=y;
    e[tot].nex=head[x];
    head[x]=tot;
}
int n,m;
int k,lim;
int f[N][15][3];
int siz[N];
int tmp[15][3];
void dfs(int x,int fa){
    siz[x]=1;
    f[x][0][0]=k-1;
    f[x][1][1]=1;
    f[x][0][2]=m-k;
    for(int p=head[x];p;p=e[p].nex){
        int y=e[p].to;
        if(y==fa)   continue;
        dfs(y,x);
        siz[x]+=siz[y];
        for(int i=0;i<=min(siz[x],lim);i++){
            tmp[i][0]=f[x][i][0];
            f[x][i][0]=0;
            tmp[i][1]=f[x][i][1];
            f[x][i][1]=0;
            tmp[i][2]=f[x][i][2];
            f[x][i][2]=0;
        }
        for(int i=0;i<=min(siz[x],lim);i++){
            for(int j=0;j<=min(siz[y],lim-i);j++){
                (f[x][i+j][0]+=(tmp[i][0]*(((f[y][j][0]+f[y][j][1])%mod+f[y][j][2])%mod)%mod)%mod)%=mod;
                (f[x][i+j][1]+=tmp[i][1]*f[y][j][0]%mod)%=mod;
                (f[x][i+j][2]+=(tmp[i][2]*((f[y][j][0]+f[y][j][2])%mod)%mod)%mod)%=mod;
            }
        }
    }
}
signed main(){
    n=read();
    m=read();
    for(int i=1;i<n;i++){
        int x,y;
        x=read();
        y=read();
        add_edge(x,y);
        add_edge(y,x);
    }
    k=read();
    lim=read();
    dfs(1,0);
    int ans=0;
    for(int i=0;i<=lim;i++){
        (ans+=((f[1][i][0]+f[1][i][1])%mod+f[1][i][2])%mod)%=mod;
    }
    cout<<ans<<endl;
    return 0;
}

本文作者:xxx2022

本文链接:https://www.cnblogs.com/xxx2022/p/17688612.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   OIer_xxx2022  阅读(206)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起