CQOI2009 葉子的染色 貪心或動規

2021-07-26 06:03:56 字數 2952 閱讀 7113

給一棵m個結點的無根樹,你可以選擇乙個度數大於1的結點作為根,然後給一些結點(根、內部結點和葉子均可)著以黑色或白色。你的著色方案應該保證根結點到每個葉子的簡單路徑上都至少包含乙個有色結點(哪怕是這個葉子本身)。

對於每個葉結點u,定義c[u]為從根結點到u的簡單路徑上最後乙個有色結點的顏色。給出每個c[u]的值,設計著色方案,使得著色結點的個數盡量少。

第一行包含兩個正整數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 有邊相連。

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

這題一看就是樹形動規,但是今天考試的時候怕寫錯,寫了個貪心,心裡想騙個80分滿足了,居然意外的ac了。

後來問了一下同學,似乎也沒有找出反例,於是我偽證了一波,貌似這個貪心是對的。。。

貪心策略:

若某結點的兒子結點中需要染黑色的比白色多,就將此節點標記為要染黑色,將要染白色的兒子染成白色;

同理若白色比黑色多反過來;

如果黑色與白色一樣多,那麼要染的個數無論如何都是兒子結點數目/2,此時將父親結點標記為待定,即染為黑色和染為白色都是一樣的,交給上面結點決策。

舉個例子

到了根節點待定還未確定,隨便染顏色均可

動規的思路其他部落格上寫的很詳細了,就簡要提一提:

f[i,0]表示以i為根的子樹中,根染黑色的最小染色數目

f[i,1]表示以i為根的子樹中,根染白色的最小染色數目

f[i,0]表示以i為根的子樹中,根不染色的最小染色數目

如果i不染色,在子結點中取乙個最小的;i染黑色,子結點就不需要染黑色了,但白色的還是要染;白色同理

貪心:

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

const

int get_int()

while(x>='0'&&x<='9')

return num*bj;

}int cnt=0,head[50005],sum=1,n,leaf,f[50005],indegree[50005],root;

struct edge edge[50005];

void addedge(int from,int to)

void treedp(int now,int father) ,color;

for(int i=head[now]; i; i=edge[i].next)

if(cnt[0]==cnt[1])color=2;

else

if(cnt[1]>cnt[0])color=1;

else color=0;

f[now]=color;

sum+=min(cnt[0],cnt[1]);

}int main()

for(int i=leaf+1; i<=n; i++)

if(indegree[i]!=1)

treedp(root,-1);

printf("%d\n",sum);

return

0;}

動規:

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

const

int get_int()

while(x>='0'&&x<='9')

return num*bj;

}int cnt=0,head[50005],n,leaf,f[50005][3];

struct edge edge[50005];

void addedge(int from,int to)

void treedp(int now,int father)

f[now][0]++;

f[now][1]++;

}int main()

for(int i=1; iint x=get_int(),y=get_int();

addedge(x,y);

addedge(y,x);

}treedp(leaf+1,-1);

printf("%d\n",min(f[leaf+1][0],min(f[leaf+1][1],f[leaf+1][2])));

return

0;}

CQOI2009 葉子的染色

首先,選擇任意乙個度數大於 1 的節點為根的最優的答案都是固定的,具體證明這裡不加贅述。我們仔細研究,他只要求根節點到葉子節點的最後乙個有色節點的顏色。我們對第 x 號節點染色,意味著我們把所有它子樹中的葉子節點最近的乙個有色節點的顏色就發生了改變。顯然,兒子越多的節點價效比越高。因此,我們定義 d...

CQOI2009 葉子的染色 樹形dp

給一棵 m 個結點的無根樹,你可以選擇乙個度數大於 1 的結點作為根,然後給一些結點著以黑色或白色。方案應保證根結點到每個葉子的簡單路徑上都至少包含乙個有色結點。對於每個葉結點 u 定義 c u 為從根結點從 u 的簡單路徑上最後乙個有色結點的顏色。給出每個 c u 的值,設計著色方案,使得著色結點...

CQOI2009 葉子的染色 性質 樹形Dp

online judge bzoj1304,luogu p3155 label 無根樹,樹形dp 給定一棵 n 個節點的無根樹,它一共有 k 個葉子節點。你可以選擇乙個度數大於1的節點作為根,並對整棵樹進行染色 對於每個節點可以染黑 白,或選擇不染 著色方案需滿足以下約束 1.每個葉子節點到樹根的路...