[CQOI2009]叶子的染色【性质+树形Dp】
Online Judge:Bzoj1304,Luogu P3155
Label:无根树,树形Dp
题目描述
给定一棵\(N\)个节点的无根树,它一共有\(K\)个叶子节点。你可以选择一个度数大于1的节点作为根,并对整棵树进行染色(对于每个节点可以染黑/白,或选择不染),着色方案需满足以下约束:
1.每个叶子节点到树根的路径上都至少存在1个有色节点; 2.对于编号为\(i\)的叶子节点,给定一个\(c[i]\),表示从叶子节点到树根路径上第一个遇到的有色节点的颜色(0:黑,1:白)。
\(M<=10000\) \(N<=5021\)
输入
第一行包含两个正整数\(N,K\)。
结点编号为\(1,2,…,N\),其中编号\(1,2,… ,K\)是叶子。
以下\(K\)行每行一个0或1的整数(0表示黑色,1表示白色),依次为c[1],c[2],…,c[n]。
以下\(m-1\)行每行两个整数a,b(1<=a < b <= m),表示结点a和b 有边相连。
输出
仅一个数,即着色结点数的最小值。
样例
Input
5 3
0
1
0
1 4
2 5
4 5
3 5
Output
2
题解
唯一的难度在于是棵无根树。
part1
如果是棵有根树怎么做。
[1]状态定义
定义状态\(f[x][0/1]\)表示节点\(x\)染为黑/白,以其为根的子树所需的最小染色数。
为什么第二维不再弄个\(2\)表示不染色时的状态呢(当然这样也可以做,但没必要),在之后的转移中我们有一个"删除儿子颜色"的操作,也就是说先染上色,到时候再根据最优性考虑删除颜色。
[2]初始化、终态
一开始所有节点,不论选黑选白都至少选了一个有色节点,赋值为1;但对于叶子节点,将他所不能第一个遇到的那个颜色赋值为INF,后面转移时就不会用到这个状态了。
初始化 : \(f[x][0/1]=1\),\(f[leaf][!c[leaf]]=INF\)
最后答案为\(ans=max(f[root][0],f[root][1])\)。只用考虑根节点染黑染白的情况。为什么无需考虑根节点不染色的情况呢,因为显然将树根染上颜色比将其某个子孙染上同种颜色会更优。
[3]转移
一遍dfs搞一下整棵树,对于非叶子节点x,其儿子为son。
如果x,son同色,则让x保留颜色,son删除颜色更优(x包含的范围更广)。如果不同色则都保留。两者取较小值传给x。
\(f[x][0]+=min(f[son][0]-1,f[son][1]);\)
\(f[x][1]+=min(f[son][1]-1,f[son][0]);\)
part2
性质:在本题中,根节点的选取对于答案没有影响。
证明:类似换根的想法,设一开始的树根为\(x\),现在要将他的某个儿子\(son\)设为根。
根据上面分析,在\(x\)做根的最优方案中,
1.x与son不会染相同的颜色;
2.x一定会染色。
不妨设那时x染为黑。
A.当son染为白时,换根后两者分别可能会影响的范围根本没有变化,所以颜色都不用改变,答案当然不会变。
B.当son不染色时,原来x可能会影响的范围是整棵树,换根后,只需将x的颜色转给son,x本身不染色即可保证树根可能影响的范围不变,这样只有这两点的颜色交换了,染色总数依然不变。
所以随便挑一个非叶子节点做根就好了。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
vector<int>e[N];
int f[N][2],n,k;
void dfs(int x,int fa){
if(x<=k)return;
for(int i=0;i<e[x].size();i++){
int y=e[x][i];if(y==fa)continue;
dfs(y,x);
f[x][0]+=min(f[y][0]-1,f[y][1]);
f[x][1]+=min(f[y][1]-1,f[y][0]);
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)f[i][0]=f[i][1]=1;
for(int i=1,w;i<=k;i++){
scanf("%d",&w),f[i][!w]=1e9;
}
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
e[u].push_back(v);e[v].push_back(u);
}
dfs(n,0);
printf("%d\n",min(f[n][0],f[n][1]));
}
[CQOI2009]叶子的染色【性质+树形Dp】的更多相关文章
- BZOJ_1304_[CQOI2009]叶子的染色_树形DP
BZOJ_1304_[CQOI2009]叶子的染色_树形DP Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白 ...
- BZOJ1304 CQOI2009 叶子的染色 【树形DP】
BZOJ1304 CQOI2009 叶子的染色 Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方 ...
- [luogu3155 CQOI2009] 叶子的染色(树形dp)
传送门 Solution 十分简单的树形dpQwQ,转移关系:父亲染了儿子不用染 只需要确定根就是简单树形dp,而其实根可以随便取一个非叶子节点 可以分情况讨论发现答案并不会改变 Code //By ...
- BZOJ1304 CQOI2009叶子的染色(树形dp)
令f[i]表示i子树内最少染色次数,加上012状态分别表示该子树内叶节点已均被满足.存在黑色叶节点未被满足.存在白色叶节点未被满足,考虑i节点涂色情况即可转移.事实上贪心也可以. #include&l ...
- 【Luogu】P3155叶子的染色(树形DP)
题目链接 树形DP水题qwq. 设f[i][j]是以i为根的子树,染成j色,且满足内部需求的最少染色节点数. 设to是x的子节点,那么状态转移方程如此设计: 1.f[i][0] 这个状态表示i不染色, ...
- BZOJ 1304: [CQOI2009]叶子的染色
1304: [CQOI2009]叶子的染色 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 566 Solved: 358[Submit][Statu ...
- 洛谷 P3155 [CQOI2009]叶子的染色 解题报告
P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到 ...
- P3155 [CQOI2009]叶子的染色
P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到 ...
- 【BZOJ1304】[CQOI2009]叶子的染色(动态规划)
[BZOJ1304][CQOI2009]叶子的染色(动态规划) 题面 BZOJ 洛谷 题解 很简单. 设\(f[i][0/1/2]\)表示以\(i\)为根的子树中,还有颜色为\(0/1/2\)(\(2 ...
- BZOJ_4033_[HAOI2015]树上染色_树形DP
BZOJ_4033_[HAOI2015]树上染色_树形DP Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的 ...
随机推荐
- Algo: Basic
1. 二维数组的查找 2. 替换空格 3. 从尾到头打印链表 4. 重建二叉树 5. 用两个栈实现队列 6. 旋转数组的最小数字 7. 斐波那契数列 8. 跳台阶 9. 变态跳台阶 10. 矩阵覆盖 ...
- IPsec分析/测试/
一 局域网拓扑图 局域网环境搭建步骤: (升级最新版本 ,恢复出厂设置后) 1 两台网关wan口直连,分别接两台pc , 2 局域网网络测试,正常情况下PC1 和PC2 互通 ,测试通过在进行ip ...
- Spring整合Dubbo框架
Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用.演示过程创建两个小工程,一个作为服务的提供者,一个作为服务的消费者.通过Dubbo来实现服务消费者远程调用服务提供者的方法. d ...
- 一个因为系统字号设置导致的rem计算渲染异常问题
测试同学突然拿着一部手机过来说,H5渲染各个元素都变大了,有些元素撑出了屏幕外面. 本来以为是某个Webview的渲染兼容问题,结果发现所有的浏览器都这样. 莫名其妙,隐约感觉是 rem计算出了问题, ...
- QString组合、拆分。
1.组合字符常用arg()函数 QString test=QString("_haha_%1_hehe%2") .arg("ee").arg("aa& ...
- Spring IOC基础回顾 — 组件扫描和装配
目录 注解形式配置应用IOC 1. 组件自动扫描 2. 组件依赖:为bean添加注解,实现自动注入 3. Spring IOC应用小结 注解形式配置应用IOC 在类定义.方法定义.成员变量定义前使用, ...
- wangEditor 菜单栏随页面滚动位置改变(吸顶)问题解决
参考:https://www.kancloud.cn/wangfupeng/wangeditor2/113980 当页面向下滚动到隐藏了菜单栏时,编辑器默认会fixed菜单栏,即让菜单栏保持『吸顶』状 ...
- LeetCode 38.报数(Python3)
题目: 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 被读作 "one 1& ...
- 笔记:Python操作sql
python操作mysql步骤: 创建connect连接 conn = connect(host='127.0.0.1', port=3306, user='root', password='1234 ...
- h5对接jssdk支付分并调用开启支付分页面
1.ws.config签名 调用ticket等获取ws.config的签名,下面会调用方法再调用方法时需要再次按照调用方法的签名 wx.config({ debug: true, // 开启调试模 ...