[USACO 2017 December Gold] Barn Painting

题目大意:

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

正文:

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

\[\begin{aligned}f_{x,0}& =(f_{y,1}+f_{y,2})f_{x,0}\quad(y\in\text{son}(x))\\f_{x,1}& =(f_{y,0}+f_{y,2})f_{x,1}\quad(y\in\text{son}(x))\\f_{x,2}& =(f_{y,0}+f_{y,1})f_{x,2}\quad(y\in\text{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;
		}
	}
}
posted @ 2020-04-26 20:36  Jayun  阅读(141)  评论(0编辑  收藏  举报