本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目链接
x中普通颜色,y中特殊颜色,要求任意两个节点如果染得都是特殊颜色要求不一样,求所有的染色方案
本题需要找好状态表示。
父节点的颜色会影响子节点的选择的颜色种类,(但是如果确定了子节点染了什么染色,无法确定父节点所染的颜色种类,所以注定是从根往子节点推)我们可以发现
-
父节点染普通颜色,子节点可以染
x种普通颜色和y种特殊颜色 -
父节点染特殊颜色,子节点可以染
x中普通颜色和y - 1种特殊颜色
便有:
- 状态表示:
状态中的根节点i只是说了染了什么种类的颜色,只是某一种颜色(该种颜色有很多类)
:i节点染普通颜色时,子树中的染色总情况(不包含i节点的染色情况,i节点只是说了染了什么种类的颜色)
:i节点染特殊颜色时,子树中的染色总情况
- 状态转移:
可能有多个子树,多个子树的情况互相独立,所以要乘起来
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 998244353;
void solve()
{
int n, x, y;
cin >> n >> x >> y;
vector<vector<int>> g(n + 1);
for(int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
vector<vector<ll>> f(n + 1,vector<ll>(2));
function<void(int, int)> dfs = [&](int u, int p) -> void
{
f[u][1] = f[u][0] = 1;
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(v == p) continue;
dfs(v, u);
f[u][1] = f[u][1] * (f[v][1] * (y - 1) % mod + f[v][0] * x % mod) % mod;
f[u][0] = f[u][0] * (f[v][1] * y % mod + f[v][0] * x % mod) % mod;
}
};
dfs(1, -1);
cout << (f[1][0] * x % mod + f[1][1] * y % mod) % mod << "\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--)
solve();
return 0;
}