【bzoj1304】[CQOI2009]叶子的染色 树形dp
題目描述
給一棵m個結(jié)點的無根樹,你可以選擇一個度數(shù)大于1的結(jié)點作為根,然后給一些結(jié)點(根、內(nèi)部結(jié)點和葉子均可)著以黑色或白色。你的著色方案應(yīng)該保證根結(jié)點到每個葉子的簡單路徑上都至少包含一個有色結(jié)點(哪怕是這個葉子本身)。 對于每個葉結(jié)點u,定義c[u]為從根結(jié)點從U的簡單路徑上最后一個有色結(jié)點的顏色。給出每個c[u]的值,設(shè)計著色方案,使得著色結(jié)點的個數(shù)盡量少。
輸入
第一行包含兩個正整數(shù)m, n,其中n是葉子的個數(shù),m是結(jié)點總數(shù)。結(jié)點編號為1,2,…,m,其中編號1,2,… ,n是葉子。以下n行每行一個0或1的整數(shù)(0表示黑色,1表示白色),依次為c[1],c[2],…,c[n]。以下m-1行每行兩個整數(shù)a,b(1<=a < b <= m),表示結(jié)點a和b 有邊相連。
輸出
僅一個數(shù),即著色結(jié)點數(shù)的最小值。
樣例輸入
5 3
0
1
0
1 4
2 5
4 5
3 5
樣例輸出
2
題解
樹形dp
考慮如果給定根節(jié)點的話怎么做:
設(shè) $f[i][j]$ 表示以 $i$ 為根的子樹,$i$ 到根節(jié)點的簡單路徑上最后一個有色節(jié)點的顏色是 $j$ 的最小著色點數(shù)。
那么對于所有 $i$ 的兒子 $k$ ,有 $f[i][j]+=min(f[k][j],f[k][j\text{^}1])$ 。邊界條件 $f[u][c[u]]=0,f[u][c[u]\text{^}1]=\infty$ ,其中 $u$ 是葉子節(jié)點。
那么 $min(f[root][0],f[root][1])+1$ 就是 $root$ 作為樹根時的答案,其中 $+1$ 指的是根節(jié)點需要再著色一次。
一次dp的時間復(fù)雜度是 $O(n)$ ,我們可以枚舉每個節(jié)點為根,復(fù)雜度為 $O(n^2)$ ,可過。
但是還有更優(yōu)的做法:考慮根節(jié)點從 $x$ 變化到相鄰的點 $y$ 的過程,那么 $x$ 為根時,$y$ 的著色只有兩種情況:染了與 $x$ 不同的顏色、沒有染色。
第一種情況顯然換根后方案可以不變,第二種情況顯然可以換根時把 $x$ 的著色該為染 $y$ ,答案不變。因此有 $ans_y\le ans_x$,同時從 $y$ 換到 $x$ 時有 $ans_x\le ans_y$ ,所以 $ans_x=ans_y$。
于是選擇任意一個非葉節(jié)點作為根做一次dp即可,時間復(fù)雜度 $O(n)$
#include <cstdio> #include <algorithm> #define N 10010 using namespace std; int head[N] , to[N << 1] , next[N << 1] , cnt , f[N][2]; inline void add(int x , int y) {to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt; } void dfs(int x , int fa) {int i;for(i = head[x] ; i ; i = next[i])if(to[i] != fa)dfs(to[i] , x) , f[x][0] += min(f[to[i]][0] , f[to[i]][1] + 1) , f[x][1] += min(f[to[i]][1] , f[to[i]][0] + 1); } int main() {int n , m , i , x , y;scanf("%d%d" , &m , &n);for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &x) , f[i][x] = 0 , f[i][x ^ 1] = m;for(i = 1 ; i < m ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);dfs(m , 0);printf("%d\n" , min(f[m][0] , f[m][1]) + 1);return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/GXZlegend/p/8059198.html
總結(jié)
以上是生活随笔為你收集整理的【bzoj1304】[CQOI2009]叶子的染色 树形dp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 遇到过的坑
- 下一篇: 2017.12.18