P4084 [USACO17DEC]Barn Painting G

还是一道很好的树形dp 但是我写了好久 一直改来改去的 还是对树形dp不是很熟练 不过还好最后A了

很容易想到dp[i,1/2/3] 表示 以i为根节点的染色方案数 1/2/3表示根节点染的颜色

转移方程:

dp[u][3]=dp[u][3]*(dp[to][1]+dp[to][2])%mod;
		
dp[u][2]=dp[u][2]*(dp[to][1]+dp[to][3])%mod;
		
dp[u][1]=dp[u][1]*(dp[to][2]+dp[to][3])%mod;

初始化:如果该点已经被染色成x了,dp[u,x]=1,剩余两个颜色设为0

如果该节点没有被染色 那么dp[u,1]=dp[u,2]=dp[u,3]=1

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=1e5+5;
const int mod=1e9+7;
ll dp[maxn][4];
int val[maxn];
vector<int>Q[maxn];
int n,k;
void dfs(int,int);
int main(){
	cin>>n>>k;
	for(int i=2;i<=n;i++){
		int aa,bb;
		cin>>aa>>bb;
		Q[aa].push_back(bb);
		Q[bb].push_back(aa);
	}
	for(int i=1;i<=k;i++){
		int id;cin>>id;
		cin>>val[id];
	}
	dfs(1,1);
	cout<<(dp[1][1]+dp[1][2]+dp[1][3])%mod<<endl;
     return 0;
}
void dfs(int u,int fa){
	if(val[u]==1)
		dp[u][1]=1,dp[u][2]=dp[u][3]=0;
	else if(val[u]==2)
	    dp[u][2]=1,dp[u][1]=dp[u][3]=0;
	else if(val[u]==3)
	    dp[u][3]=1,dp[u][1]=dp[u][2]=0;
	else dp[u][1]=dp[u][2]=dp[u][3]=1;
	for(int i=0;i<Q[u].size();i++){
		int to=Q[u][i];
		if(to==fa)continue;
		dfs(to,u);
		dp[u][3]=dp[u][3]*(dp[to][1]+dp[to][2])%mod;
		dp[u][2]=dp[u][2]*(dp[to][1]+dp[to][3])%mod;
		dp[u][1]=dp[u][1]*(dp[to][2]+dp[to][3])%mod;
	}

}
posted @ 2022-03-31 15:39  wzx_believer  阅读(31)  评论(0)    收藏  举报