【CQOI2009】【C++心路历程39】叶子的颜色【贪心】

网上题解dp很多了~这里发一个贪心的。
其实很自然,对于叶子节点的父亲,黑/白色哪种颜色的数量更多,这个父亲就应该染成哪种颜色(如图)。而当黑白数目相同时,染成哪种颜色实际上是无所谓的。

证明:
那么,对于每个父亲和他的所有儿子,都符合最优子结构。并且满足眼前看起来最优的策略。
【CQOI2009】【C++心路历程39】叶子的颜色【贪心】_第1张图片
那么,我们再向上一层考虑。

【CQOI2009】【C++心路历程39】叶子的颜色【贪心】_第2张图片
对于最顶端的父亲节点,我们发现为0的儿子有1个,为1的儿子有2个,这时我们就应该将顶端节点染成1。有人可能会问:万一为0的那个儿子黑白比特别大呢?
【CQOI2009】【C++心路历程39】叶子的颜色【贪心】_第3张图片
我们发现,对于那个为0的儿子结点,把父亲染成黑或者把他自己染成黑其效果是一样的。但是如果把父亲染成白,对于另外数量占优的白色节点来说,就会少染一些点。其实,这也正好反映了贪心“只看眼前最优”的思想。

具体代码实现,我们将ans的初值定为1,意即根节点先染上色。每次计算i和他的儿子时,将他儿子的黑白数量少的那个染上相应的颜色,多的那个用根节点(先加的那个1)去染色。

void dfs(int i,int f)
{
    int wh=0,bl=0;
    if(i<=n) return ;
    for(int p=first[i];p;p=E[p].next)
    {
        int j=E[p].to;
        if(j==f) continue;
        dfs(j,i);
        if(c[j]==0) bl++;
        if(c[j]==1) wh++;
    }
    if(bl>wh) c[i]=0;
    else if(bl1;
    else c[i]=-1;
    ans+=min(bl,wh);
}

你可能感兴趣的:(【CQOI2009】【C++心路历程39】叶子的颜色【贪心】)