日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【bzoj1304】[CQOI2009]叶子的染色 树形dp

發(fā)布時間:2024/4/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【bzoj1304】[CQOI2009]叶子的染色 树形dp 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目描述

給一棵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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。