葉子的染色(樹型dp)

2021-09-26 07:18:48 字數 1269 閱讀 2759

給一棵m個結點的無根樹,你可以選擇乙個度數大於1的結點作為根,然後給一些結點(根、內部結點和葉子均可)著以黑色或白色。你的著色方案應該保證根結點到每個葉子的簡單路徑上都至少包含乙個有色結點(哪怕是這個葉子本身)。 對於每個葉結點u,定義c[u]為從根結點從u的簡單路徑上最後乙個有色結點的顏色。給出每個c[u]的值,設計著色方案,使得著色結點的個數盡量少。

input

第一行包含兩個正整數m, n,其中n是葉子的個數,m是結點總數。結點編號為1,2,…,m,其中編號1,2,… ,n是葉子。以下n行每行乙個0或1的整數(0表示黑色,1表示白色),依次為c[1],c[2],…,c[n]。以下m-1行每行兩個整數a,b(1<=a < b <= m),表示結點a和b 有邊相連。

output

僅乙個數,即著色結點數的最小值。

sample input

5 3010

1 42 5

4 53 5

sample output

2hint

m<=10000

n<=5021

題意:給一棵m個結點的根樹,你可以選擇乙個度數大於1的結點作為根,然後給一些結點(根、內部結點和葉子均可)著以黑色或白色。你的著色方案應該保證根結點到每個葉子的簡單路徑上都至少包含乙個有色結點(哪怕是這個葉子本身)。 對於每個葉結點u,定義c[u]為從根結點從u的簡單路徑上最後乙個有色結點的顏色。給出每個c[u]的值,設計著色方案,使得著色結點的個數盡量少。

轉移方程:dp[root][0]+=min(dp[e[i].to][0]-1,dp[e[i].to][1]);

dp[root][1]+=min(dp[e[i].to][1]-1,dp[e[i].to][0]);

**:

#include#include#include#includeusing namespace std;

const int inf=0x3f3f3f3f;

const int maxn=10005;

int m,n,c[maxn],head[maxn],cnt,dp[maxn][2];

struct edgee[maxn*2];

void add_edge(int u,int v)

void dfs(int root,int fa)

for(int i=head[root];i!=-1;i=e[i].next)

if(e[i].to!=fa)

}int main()

dfs(n+1,-1);

cout

}

葉子的染色

有乙個 m 個節點的樹,可以選擇乙個度大於 1 的節點作為根,並將一些點染為白色或黑色,染色方案因保證根到每個葉子節點的路徑上都至少有乙個有色節點,並且路徑上離葉子結點最近的節點顏色為 c i 我們考慮選哪個節點為根不影響答案的選擇,因為我們只需要維護葉子節點上方最近的有顏色節點,非葉節點是否為根並...

樹DP 樹上染色

haoi2015 樹上染色 時間限制 1 s 記憶體限制 256 mb 題目描述 有一棵點數為n的樹,樹邊有邊權。給你乙個在0 n之內的正整數k,你要在這棵樹中選擇k個點,將其染成黑色,並將其他的n k個點染成白色。將所有點染色後,你會獲得黑點兩兩之間的距離加上白點兩兩之間距離的和的收益。問收益最大...

樹DP 樹上染色

haoi2015 樹上染色 時間限制 1 s 記憶體限制 256 mb 題目描述 有一棵點數為n的樹,樹邊有邊權。給你乙個在0 n之內的正整數k,你要在這棵樹中選擇k個點,將其染成黑色,並將其他的n k個點染成白色。將所有點染色後,你會獲得黑點兩兩之間的距離加上白點兩兩之間距離的和的收益。問收益最大...