题目大意

  给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根、内部结点和叶子均可)着以黑色或白色。你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身)。 对于每个叶结点u,定义c[u]为从根结点从U的简单路径上最后一个有色结点的颜色。给出每个c[u]的值,设计着色方案,使得着色结点的个数尽量少。

题解

选什么根都一样

  证明思路是先证明一步,然后由此推广到所有可能。我们先证明:把一个根(以后简称“原根”)换为它的儿子(以后简称“新根”),最优情况不变。我们假定原根与新根的颜色要么不变要么交换。首先原根的、不以新根为根的子树内的叶子节点是不会受到影响的,因为它们到根的路径延长了,该遇到颜色的节点总会遇到的。那么以对于新根为子树内的叶子节点呢?如果原根与新根都有颜色,那么结果毫无影响,因为原根与新根的颜色肯定不相同(如果相同,把新根变为透明依然满足要求,结果却变小了),此时这个子树内不可能存在一个叶子节点,它到根节点路径上的第一个颜色为c[那个叶子]的结点(以后简称那个叶子“依赖”的结点)就是原根(因为经过了一个颜色不相同的结点新根)。唯一特殊的情况便是原根有颜色,新根是透明。换为新根后,依赖于原根的叶子结点便没有了依赖的对象了。怎么办?把原根与新根颜色交换就都满足要求了。

  综上所述,把现有的根换为当前根的儿子,结果不变。那么随便找另一个点作为根,那个点必然是当前根的儿子的儿子的儿子的儿子...,故答案也不变。所以,选什么根都一样。

动规

  树上求最值,往往要用树上DP。树上DP的子问题往往在子树中。问题在于:树与子树间的联系是什么?我们的思维可能会卡在我们的经验,也就是动规的子问题都是往往都是在局部将问题彻底解决。而这道题不一样,一个子树内的叶子结点所依赖的结点很有可能不在子树内。所以我们应当这样思考:当前问题的解决方案由子问题怎样改造而来的?

  我们先暂时用cur->DP来表示以cur为子树时,最少多少个结点需要染色。我们此时需要画一画。这时,我们发现在一个子问题中,根节点被染色的最优方案一定属于最优方案的集合中,因为任何根节点没有被染色的最优方案都可以通过将离根节点最近的染色结点的颜色转移到根节点上(以后简称“颜色转移根操作”)的方法转化为根节点被染色的最优方案。所以我们就令所有子问题的解根节点都被染色。当然如果只给一个DP问题不单纯,我们要将DP分为DP[0],DP[1]表示根节点染成黑色和染成白色时的最优解。首先要清楚一点,拿DP[0]为例,对于一个子树,如果我们要选择子树根为黑色的方案,因为cur就是黑色,所以在以cur为根的染色方案中,该子树根将要改为透明,故该子树内染色的节点数为cur->Son->DP[0]-1;如果要选择子树根为白色的方案,在以cur为根的方案中,该子树的染色方案不变,仍然为cur->Son->DP[1]。所以cur->DP[0]=1+sum(i){min{cur->Son[i]->DP[0]-1,cur->Son[i]->DP[1]}}。cur->DP[1]同理。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int MAX_NODE = 10010, INF = 0x3f3f3f3f;
int TotLeaf, TotNode; struct Node
{
vector<Node*> Next;
int ColorWant;
int F[2];
}_nodes[MAX_NODE]; void Dfs(Node *cur, Node *fa)
{
if (cur - _nodes <= TotLeaf)
return;
cur->F[0] = cur->F[1] = 1;
for (int i = 0; i < cur->Next.size(); i++)
{
Node *next = cur->Next[i];
if(next == fa)
continue;
Dfs(next, cur);
cur->F[0] += min(next->F[0] - 1, next->F[1]);
cur->F[1] += min(next->F[1] - 1, next->F[0]);
}
} int main()
{
scanf("%d%d", &TotNode, &TotLeaf);
for (int i = 1; i <= TotLeaf; i++)
scanf("%d", &_nodes[i].ColorWant);
for (int i = 1; i <= TotLeaf; i++)
{
_nodes[i].F[_nodes[i].ColorWant] = 1;
_nodes[i].F[!_nodes[i].ColorWant] = INF;
}
for (int i = 1; i <= TotNode - 1; i++)
{
int u, v;
scanf("%d%d", &u, &v);
_nodes[u].Next.push_back(_nodes + v);
_nodes[v].Next.push_back(_nodes + u);
}
for (int i = TotLeaf + 1; i <= TotNode; i++)
_nodes[i].F[0] = _nodes[i].F[1] = 0;
Dfs(_nodes + TotLeaf + 1, NULL);
printf("%d\n", min(_nodes[TotLeaf + 1].F[0], _nodes[TotLeaf + 1].F[1]));
return 0;
}

  

luogu3155 [CQOI2009]叶子的染色的更多相关文章

  1. [luogu3155 CQOI2009] 叶子的染色(树形dp)

    传送门 Solution 十分简单的树形dpQwQ,转移关系:父亲染了儿子不用染 只需要确定根就是简单树形dp,而其实根可以随便取一个非叶子节点 可以分情况讨论发现答案并不会改变 Code //By ...

  2. BZOJ 1304: [CQOI2009]叶子的染色

    1304: [CQOI2009]叶子的染色 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 566  Solved: 358[Submit][Statu ...

  3. 洛谷 P3155 [CQOI2009]叶子的染色 解题报告

    P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到 ...

  4. 【BZOJ1304】[CQOI2009]叶子的染色(动态规划)

    [BZOJ1304][CQOI2009]叶子的染色(动态规划) 题面 BZOJ 洛谷 题解 很简单. 设\(f[i][0/1/2]\)表示以\(i\)为根的子树中,还有颜色为\(0/1/2\)(\(2 ...

  5. P3155 [CQOI2009]叶子的染色

    P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到 ...

  6. BZOJ1304 CQOI2009 叶子的染色 【树形DP】

    BZOJ1304 CQOI2009 叶子的染色 Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方 ...

  7. BZOJ_1304_[CQOI2009]叶子的染色_树形DP

    BZOJ_1304_[CQOI2009]叶子的染色_树形DP Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白 ...

  8. CQOI2009叶子的染色

    叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一 ...

  9. bzoj千题计划233:bzoj 1304: [CQOI2009]叶子的染色

    http://www.lydsy.com/JudgeOnline/problem.php?id=1304 结论1:根节点一定染色 如果根节点没有染色,选择其子节点的一个颜色,那么所有这个颜色的子节点都 ...

随机推荐

  1. JavaScript中的 函数splice() 的使用。

    大二接触JavaScript初期,学习函数中有一道题: 定义一个2个参数的函数.第1个参数是一个数组,第2个参数是需要删除的元素.函数功能,在第1个实参数组中查找第2个实参提供的值,找到则删除该元素( ...

  2. Ajax——jq中ajax的使用

    格式化表单 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  3. html5——2D转换

    transform 属性 1.向元素应用 2D 或 3D 转换 2.该属性允许我们对元素进行旋转.缩放.移动或倾斜. 缩放与位移 transform: scale(, 0.5);//水平缩放,垂直缩放 ...

  4. 重绘DataGridView标头

    最近突然想在DataGridView标头放置一个CheckBox,我就想着重写下DataGridViewColumnHeaderCell抱着试试的心态结果真的是可以的下面是源码:(如果有看不懂的可以加 ...

  5. Java_Web三大框架之Hibernate 入门(一)

    一.Hibernate简介: Hibernate作者——Gavin King Hibernate创始人 < Hibernate in action >作者 EJB 3.0的Entity b ...

  6. 2016.01.05 DOM笔记(一) 查找元素

    DOM节点的种类 元素和标签是一个意思,例如<body>标签或者称为<body>元素 节点DOM的节点分为三类  元素节点,文本节点,属性节点 例如 <div id=‘b ...

  7. [文章转载]-Java后端,应该日常翻看的中文技术网站 -江南白衣

    Java后端,应该日常翻看的中文技术网站 1.内容生产者 InfoQ 中文技术第一站,佩服霍老板,真金白银地为中国程序员们生产内容. ImportNew 专门面向Java的内容生产者兼聚合者,偶然也有 ...

  8. Centos6.4 安装fail2ban防暴力破解

    Centos6.4 安装fail2ban防暴力破解 一. 安装 curl -O https://codeload.github.com/fail2ban/fail2ban/tar.gz/0.9.0 m ...

  9. 转录组入门(3):了解fastq测序数据

    sra文件转换为fastq格式 fastq-dump -h --split-3 也就是说如果SRA文件中只有一个文件,那么这个参数就会被忽略.如果原文件中有两个文件,那么它就会把成对的文件按*_1.f ...

  10. 内网jenkins如何配置gitlab自动拉取代码打包

    在全局工具配置中添加git安装目录的配置 http://10.2.1.92:8080/jenkins/configureTools/git1.8.3.1/usr/bin/git 打开系统设置配置git ...