[洛谷 P4084 USACO17DEC] Barn Painting G (树形dp经典)
生活随笔
收集整理的這篇文章主要介紹了
[洛谷 P4084 USACO17DEC] Barn Painting G (树形dp经典)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[洛谷 P4084 USACO17DEC] Barn Painting G
題目鏈接
大致題意:
給定一顆N個節點組成的樹,3種顏色,其中K個節點已染色,要求任意兩相鄰節點顏色不同,求合法染色方案數
解題思路:
-
f[i][j]表示i這個點上色為j是方案數(從下往上/從子節點向父節點更新)
-
即對于所有初始節點,f[i][1],f[i][2],f[i][3]都為1
-
當某個節點被指定上色后,那么該節點另外兩種顏色的方案數為0。
列如:當點x被指定上色 2 時:f[x][1]=0,f[x][3]=0 (因為無法上色1和3)
-
對于每個節點,因為不能于子節點上色相同,即:
- 最后,記得取模和開long long
AC代碼:
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; typedef pair<int, int> PII; typedef long long ll; const int N = 1e5 + 10, mod = 1e9 + 7; int n, m; vector<int>e[N]; ll f[N][5]; //i點涂j顏色的方案數 void dfs(int u, int fa) {//初始化for (int i = 1; i <= 3; ++i) {if (f[u][i]) {for (int j = 1; j < i; ++j)f[u][j] = 0;break;}f[u][i] = 1;}for (auto& v : e[u]) {if (v == fa)continue;dfs(v, u);f[u][1] = f[u][1] * ((f[v][2] + f[v][3]) % mod) % mod;f[u][2] = f[u][2] * ((f[v][1] + f[v][3]) % mod) % mod;f[u][3] = f[u][3] * ((f[v][1] + f[v][2]) % mod) % mod;} } int main(void) {cin >> n >> m;for (int i = 1; i < n; ++i) {int a, b; cin >> a >> b;e[a].push_back(b);e[b].push_back(a);}while (m--) {int a, b; cin >> a >> b;f[a][b] = 1;}dfs(1, -1);ll res = (f[1][1] + f[1][2] + f[1][3]) % mod;cout << res << endl;return 0; }總結
以上是生活随笔為你收集整理的[洛谷 P4084 USACO17DEC] Barn Painting G (树形dp经典)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj 4084:拓扑排序
- 下一篇: [转载] 蒲慕明写给学生的信