题目大意:
给定一颗 (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;
}
}
}