传送门:https://www.luogu.org/problemnew/show/P3155

一道挺水的树形dp题,然后我因为一个挺智障的问题debug了一晚上……

嗯……首先想,如果一个点的颜色和他的儿子相同,那么删去他儿子的颜色显然不影响,而且更符合最优解,然后我们dp时就从子树开始往上找,将儿子的状态转移给父亲时,就将儿子的颜色删去。

所以开一个dp[maxn][2],

dp[i][0]表示节点i染成黑色,以i为根的子树最少需要染色的点数。

dp[i][1]节点i染成白色,以i为根的子树最少需要染色的点数。

所以

dp[i][0] = 1+∑min(dp[j][0] - 1, dp[j][1]) (j取遍i的儿子)
dp[i][1] = 1+∑min(dp[i][0], dp[i][1] - 1) (j取遍i的儿子)

然后直接贴代码

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<vector>
using namespace std;
#define enter printf("\n")
#define space printf(" ")
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 5e4 + ;
//const int maxm = 1e4 + 5;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch))
{
ans = ans * + ch - ''; ch = getchar();
}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar('' + x % );
} int n, m, c[maxn];
vector<int> v[maxn];
bool vis[maxn];
int dp[maxn][]; //0:染成黑色,1:染成白色
void dfs(int now)
{
vis[now] = ;
if(now <= n) return;
dp[now][] = ; dp[now][] = ;
for(int i = ; i < (int)v[now].size(); ++i)
{
if(!vis[v[now][i]])
{
dfs(v[now][i]);
dp[now][] += min(dp[v[now][i]][] - , dp[v[now][i]][]);
dp[now][] += min(dp[v[now][i]][] - , dp[v[now][i]][]);
}
}
} int main()
{
m = read(), n = read();
for(int i = ; i <= n; ++i)
{
c[i] = read();
dp[i][c[i]] = ; dp[i][c[i] ^ ] = INF;
}
for(int i = ; i < m; ++i)
{
int a = read(), b = read();
v[a].push_back(b); v[b].push_back(a);
}
dfs(n + );
write(min(dp[n + ][], dp[n + ][])); enter;
return ;
}

好了,现在讲讲为啥写代码10分钟,debug数小时。

其实就是对于无向图所走边的判重问题。

众所周知,用一个vis数组就能解决,然后因人而异在dfs开头标记或是在if(!vis[i]) 后 vis[j] = 1 (j为i的孩子).

然后我就是第二种写法。

然而

这会错

因为

根节点

没有

打!上!标!记!

所以,请务必vis[n + 1] = 1后,在dfs(n + 1)…………

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

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

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

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

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

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

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

  4. P3155 [CQOI2009]叶子的染色

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

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

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

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

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

  7. CQOI2009叶子的染色

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

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

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

  9. 【bzoj1304】[CQOI2009]叶子的染色 树形dp

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

  10. luogu3155 [CQOI2009]叶子的染色

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

随机推荐

  1. (六)彻底理解synchronized

    1.sychronized简介 在学习知识之前,我们先来看一个现象 public class SynchronizedDemo implements Runnable { private static ...

  2. 【Java基础】8、java中的native方法

    native是与C++联合开发的时候用的!java自己开发不用的! 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用.这些函 ...

  3. Math Magic(完全背包)

    Math Magic Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Sta ...

  4. 【C#数据结构系列】栈和队列

    一:栈 栈和队列也是线性结构,线性表.栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制.栈的操作只能在表的一端进行,队列的插入操作 ...

  5. 一道很好的mysql面试练习题,having综合应用

    写一条SQL语句,求出2门以及2门以上不及格的科目平均分 >要出现2门以及2门以上的学科不及格 >计算该考生所有学科的平均分,不单是,不及格的那几门 #创建表: create table ...

  6. LeetCode DB: Duplicate Emails

    Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...

  7. vue2.0父子组件通信的方法

    vue2.0组件通信方法:props传值和emit监听.(.sync方法已经移除.详情请点击)(dispatch-和-broadcast方法也已经废弃) props方法传值:Props 现在只能单项传 ...

  8. python网络爬虫抓取动态网页并将数据存入数据库MySQL

    简述以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网页 ...

  9. Java内部类的介绍

    在Java的面向对象编程中,由于Java并没有类似C++的多重继承,所以采用了内部类这样的方式,现在介绍几种内部类的常见情况. 公开内部类 即由public关键词修饰的内部类,内部类作为外部类的一个成 ...

  10. Android之使用枚举利弊及替代方案

    Android上不应该使用枚举,占内存,应该使用@XXXDef注解来替代 使用 Enum 的缺点 每一个枚举值都是一个对象,在使用它时会增加额外的内存消耗,所以枚举相比与 Integer 和 Stri ...