Codeforces 855C. Helga Hufflepuff's Cup----树形DP
z最近在学习树形DP...好难啊。
在cf上找到了一题c题当模版马克一下。
题目不贴了。。>>http://codeforces.com/problemset/problem/855/C<<
题目的意思就是给你一棵有n个节点的树,m个关系,每个节点需要上色,一共有K种颜色,其中有一个最大色,与他相邻的节点只能上比他“小”的颜色。并且最多有X个节点可以染最大色。求问染色方法有多少种。
代码如下:
#include<vector> #include<algorithm> #include<iostream> #include<string.h> #include<math.h> using namespace std; const int mod=1e9+7; int n,m,K,X; vector<int> e[100010];//用来存储树枝(双向) long long dp[100010][12][3];//dp主体,分别表示节点、选择最大色的节点数,最后一个空的0,1,2分别表示“选比最大色小的颜色时”
//“选最大色时”、“选比最大色大的颜色时”
int sz[100010]={0};//表示递归到该节点时已选最大色的数目
int t[12][3];
int sz[100010]={0};
int t[12][3];
long long dfs(int x,int pre)
{
	dp[x][0][0]=K-1;
	dp[x][1][1]=1;
	dp[x][0][2]=m-K;
	sz[x]=1;
	int i,xx,j,k;
	for(i=0;i<e[x].size();i++)
	{
		xx=e[x][i];
		if(xx==pre) continue;
		dfs(xx,x);
		memset(t,0,sizeof(t));
		for(j=0;j<=sz[x];j++)
		for(k=0;k<=sz[xx];k++)
		{
			if(j+k>X) continue;
			t[j+k][0]=(t[j+k][0]+(dp[x][j][0]*(dp[xx][k][0]+dp[xx][k][1]+dp[xx][k][2]))%mod)%mod;
			t[j+k][1]=(t[j+k][1]+(dp[x][j][1]*dp[xx][k][0]%mod))%mod;
			t[k+j][2]=(t[k+j][2]+(dp[x][j][2]*(dp[xx][k][0]+dp[xx][k][2])%mod))%mod;
		}
		sz[x]=min(sz[x]+sz[xx],X);
		for(j=0;j<=sz[x];j++)
		for(k=0;k<=2;k++)
		{
			dp[x][j][k]=t[j][k];
		}
	}
}
int main()
{
	int i,j,k,q,w;
	while(cin>>n>>m)
	{
		long long ans=0;
		for(i=1;i<=n;i++) e[i].clear();
		for(i=1;i<n;i++)
		{
			cin>>q>>w;
			e[q].push_back(w);
			e[w].push_back(q);
		}
		cin>>K>>X;
		dfs(1,-1);
		for(j=0;j<=sz[1];j++)
		for(k=0;k<=2;k++)
		ans=(ans+dp[1][j][k])%mod;
		cout<<ans<<endl;
	}
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号