传送门: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. 【模板】堆优化 + dij +pair 存储

    就是短 感谢Cptraserdalao的博客 #include<bits/stdc++.h> using namespace std; struct node { int val,num; ...

  2. String的equals()方法源码解析

    每个String对象在创建的时候都构造了一个char类型的final声明的不可替换数组,数组中的每一个元素即字符串对应的每一个字符如图: String的equals()在比较的时候会进行两步比较: 1 ...

  3. Java基础——工厂模式

    通过学习,一句话概括Java工厂模式的特点——通过建立一个工厂来创建对象,不必关心构造对象实例能不能被实例化啊等诸多细节和复杂过程. 工厂模式呢?就像我们从劳动密集型社会转型到技术密集型社会.打个比方 ...

  4. Mac安装Vue-cli时 提示bash: vue: command not found问题

    1:   首先执行sudo npm install --global vue-cli 2: 复制的路径地址为添加环境变量的地址 3:添加环境变量   export PATH="$PATH:( ...

  5. grafana-simple-json-datasource 用于连接各种grafana不支持的数据源

    https://grafana.com/plugins/grafana-simple-json-datasource 1.安装方法很简单,下载后解压放到plugins目录就好. 我的是解决版的graf ...

  6. jquery 简单归纳 -- 前端知识

    jquery 什么是jQuery? jquery是轻量级的JavaScript库,核心是javascript,兼容css和各种浏览器,核心理念是写得少做得多(write less do more). ...

  7. 001Git & GitHub

    01.创建GitHub账号 请点击标题链接,阅读官网帮助 02.创建代码仓库 请点击标题链接,阅读官网帮助 03.安装Git 注:Git官网下载太慢,可在[360卫士]-->[软件管家]中搜索下 ...

  8. hihocoder [Offer收割]编程练习赛12 [1495] ---- 矩形分割

    原题链接 矩形分割 算法分析: 解决该题要用到"并查集"的思想. 这里有一篇不错的博客介绍并查集: 并查集(Union-Find)算法介绍 记 int total=N*M,这里会有 ...

  9. RecyclerView源码解析 - 分割线

    猜想:   既然考虑了分割线,那么子View在测量时候肯定要去考虑分割线留出的位置    直接measureChild()方法 猜想: 分割线会调用绘制的方法 onDraw()

  10. C#和C++互相操作 结构体数组的传递

    C++中结构体定义: typedef struct // 平面 { double time;  float normal[3]; float center[3];  } plane; C++中方法声明 ...