CodeForces 855C Helga Hufflepuff's Cup(树形dp)

来源:互联网 发布:iphone4s越狱软件 编辑:程序博客网 时间:2024/05/21 12:39

Helga Hufflepuff's Cup

time limit per test:2 seconds

memory limit per test:256 megabytes

input:standard input

output:standard output

Harry, Ron and Hermione have figured out that Helga Hufflepuff's cup is a horcrux. Through her encounter with Bellatrix Lestrange, Hermione came to know that the cup is present in Bellatrix's family vault in Gringott's Wizarding Bank.

The Wizarding bank is in the form of a tree with total n vaults where each vault has some type, denoted by a number between1 to m. A tree is an undirected connected graph with no cycles.

The vaults with the highest security are of type k, and all vaults of typek have the highest security.

There can be at most x vaults of highest security.

Also, if a vault is of the highest security, its adjacent vaults are guaranteed to not be of the highest security and their type is guaranteed to be less thank.

Harry wants to consider every possibility so that he can easily find the best path to reach Bellatrix's vault. So, you have to tell him, given the tree structure of Gringotts, the number of possible ways of giving each vault a type such that the above conditions hold.

Input

The first line of input contains two space separated integers, n and m — the number of vaults and the number of different vault types possible. (1 ≤ n ≤ 105, 1 ≤ m ≤ 109).

Each of the next n - 1 lines contain two space separated integersui andvi (1 ≤ ui, vi ≤ n) representing the i-th edge, which shows there is a path between the two vaultsui andvi. It is guaranteed that the given graph is a tree.

The last line of input contains two integers k andx (1 ≤ k ≤ m, 1 ≤ x ≤ 10), the type of the highest security vault and the maximum possible number of vaults of highest security.

Output

Output a single integer, the number of ways of giving each vault a type following the conditions modulo109 + 7.

Examples
Input
4 21 22 31 41 2
Output
1
Input
3 31 21 32 1
Output
13
Input
3 11 21 31 1
Output
0



        给树进行染色,有一个特殊的颜色,要求这个特殊的颜色不能相互连接,然后与特殊颜色相邻的颜色编号必须小于他,问总共的涂色方案。

        这题颜色数量看似可以很多很复杂,但是解题的关键就在于对这个颜色的分类。总体来说,我可以把颜色分成三个类:0类颜色表示特殊颜色;1类颜色表示可以和特殊颜色相连的颜色,即编号小于特殊颜色的颜色;2类颜色,表示不能与特殊颜色相连的颜色,即编号大于特殊颜色编号的颜色。这样分类之后,问题一下子简化了非常的多。再加上有特殊颜色数量的最大限制,这个限制最大是10,所以我们可以很容易的写出状态转移方程。

        dp[x][i][j]表示在以x为根的子树中,有i个特殊颜色,然后当前点颜色为j的方案数。转移就分类处理,对于当前颜色为0的,dp[x][i+k][0]+=Σdp[son][k][1]*dp[x][i][0];对于当前颜色为1类的,dp[x][i+k][1]+=Σ(dp[son][k][0]+dp[son][k][1]+dp[son][k][2])*dp[x][i][1];对于当前颜色为2类的,dp[x][i+k][2]+=Σ(dp[son][k][1]+dp[son][k][2])*dp[x][i][2]。特别注意这个转移方程是+=,这也就意味着我们必须要多开一个数组,表示在某一层的dp值,因为如果不多开,新产生的值会对后面的转移产生影响。具体见代码:

#include <bits/stdc++.h>#define mod 1000000007#define LL long long#define N 100010using namespace std;LL dp[11][3],f[N][11][3];int n,m,K,sz[N],c;vector<int> g[N];void dfs(int x,int fa){    sz[x]=1;    f[x][1][0]=1;//第零类颜色对应只有一种,而且特殊颜色数量要为1    f[x][0][1]=K-1;//第一类颜色总共有K-1种    f[x][0][2]=c-K;//第二类颜色总共有c-K种    for(int i=0;i<g[x].size();i++)    {        int y=g[x][i];        if (y==fa) continue;        dfs(y,x); sz[x]+=sz[y];        memset(dp,0,sizeof(dp));        for(int j=0;j<=sz[x]&&j<=m;j++)            for(int k=0;k<=sz[y]&&j+k<=m;k++)            {                dp[j+k][0]=(dp[j+k][0]+f[x][j][0]*f[y][k][1]%mod)%mod;//三种颜色状态的转移                dp[j+k][2]=(dp[j+k][2]+f[x][j][2]*(f[y][k][1]+f[y][k][2])%mod)%mod;                dp[j+k][1]=(dp[j+k][1]+f[x][j][1]*(f[y][k][0]+f[y][k][1]+f[y][k][2])%mod)%mod;            }        for(int j=0;j<=sz[x]&&j<=m;j++)            for(int k=0;k<3;k++)                f[x][j][k]=dp[j][k];//多开一个数组表示节点内的dp,防止对后面产生影响    }}int main(){    scanf("%d%d",&n,&c);    for(int i=1;i<n;i++)    {        int u,v; scanf("%d%d",&u,&v);        g[u].push_back(v); g[v].push_back(u);    }    scanf("%d%d",&K,&m);    dfs(1,0); LL ans=0;    for(int i=0;i<=m;i++)        for(int j=0;j<3;j++)            ans=(ans+f[1][i][j])%mod;    printf("%I64d\n",ans);}

原创粉丝点击