[USACO 2017 December Gold] Barn Painting

题目大意:

给定一颗 (N) 个节点组成的树,( exttt{3}) 种颜色,其中 (K) 个节点已染色,要求任意两相邻节点颜色不同,求合法染色方案数。

正文:

考虑用树形DP,设 (f_{x,i}) 表示节点 (x) 为根的子树且它涂了颜色 (i) 的的染色方案。那么动态转移方程就显而易见了:

[egin{aligned}f_{x,0}& =(f_{y,1}+f_{y,2})f_{x,0}quad(yin ext{son}(x))\f_{x,1}& =(f_{y,0}+f_{y,2})f_{x,1}quad(yin ext{son}(x))\f_{x,2}& =(f_{y,0}+f_{y,1})f_{x,2}quad(yin ext{son}(x))end{aligned} ]

代码:


void dfs(int x, int fa)
{
	for (int y = 0; y < 3; y++)
	{
		if(f[x][y] == 1)
		{
			for (int y1 = 0; y1 < y; y1++)
				f[x][y1] = 0;
			break;
		}
		f[x][y] = 1;
	}
	for (int i = head[x]; i; i = e[i].next)
	{
		int v = e[i].to;
		if(v != fa)
		{
			dfs(v, x);
			f[x][0] = f[x][0] * ((f[v][1] + f[v][2]) % mod) % mod;
			f[x][1] = f[x][1] * ((f[v][0] + f[v][2]) % mod) % mod;
			f[x][2] = f[x][2] * ((f[v][0] + f[v][1]) % mod) % mod;
		}
	}
}
原文地址:https://www.cnblogs.com/GJY-JURUO/p/12782084.html