题意

给定一个结点颜色红或黑的树,问最少进行多少次交换黑、红结点使得每个红结点离最近的黑结点距离\(\leq x\)。

\(1\leq n \leq 500, 1 \leq x \leq 10^9\)

题解

不是红黑树

据说可有单纯形做,这里讲的还是树形dp的做法

考虑交换比较费劲,直接在\(n\)个结点里选\(m\)个(\(m\)是黑结点个数),如果原来是红结点产生\(1\)的代价

\(dp[u][k][a]\)表示\(u\)子树内选了\(k\)个黑点,\(u\)选择的黑结点是\(a\)(这里为了方便,不定义为最近的黑结点)的最小代价(若\(a\)在子树外,不考虑\(a\)的代价)。这个状态相当于树形背包加一维。

考虑转移:新加入了子树\(v\)。原信息\(dp[u][su][a]\),子树信息\(dp[v][su][b]\)

  1. \(a=b\):加起来转移到\(dp[u][su + sv][a]\)上。
  2. \(b\)在\(v\)子树中:此时a一定不在\(v\)子树中。如果在子树中只要考虑\(a = b\),上面考虑过了。加起来转移到\(dp[u][su + sv][a]\)。(实现时直接对于每个子树外的\(a\)加上最小dp值就好)
  3. \(b\)在\(v\)子树外:这时候\(a\not =b\)一定是不优的。\(a\)在\(v\)子树内,把b改\(a\)不会更差;a也不在\(v\)子树中,让\(a=b\)或\(b=a\)一定有一种不会更差。所以不转移。

注意使用short类型防止MLE。

#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 505;
struct Edge {
short v, nxt; int w;
} e[N * 2];
short hd[N], sz[N], pos[N], w[N], n, m, ec;
short dl[N], dr[N], idx, dp[N][N][N], t[N][N];
int x, dis[N][N];
void clr() {
fill(hd + 1, hd + n + 1, -1); ec = 0;
}
void add(short u, short v, int w) {
e[ec] = (Edge) {v, hd[u], w}; hd[u] = ec ++;
}
void dfs0(int *d, int u, int fa = 0) {
if(!fa) d[u] = 0;
for(int i = hd[u]; ~ i; i = e[i].nxt) {
Edge &p = e[i];
if(p.v != fa) {
d[p.v] = min(x + 1, d[u] + p.w);
dfs0(d, p.v, u);
}
}
}
void dfs1(int u, int fa = 0) {
dl[u] = ++ idx; pos[idx] = u;
for(int i = hd[u]; ~ i; i = e[i].nxt) {
int v = e[i].v;
if(v != fa) dfs1(v, u);
}
dr[u] = idx;
}
void dfs(int u, int fa = 0) {
for(int v = 1; v <= n; v ++) {
if(dis[u][v] <= x && u != v) {
dp[u][0][v] = 0;
}
}
dp[u][1][u] = w[u] ^ 1; sz[u] = 1;
for(short i = hd[u]; ~ i; i = e[i].nxt) {
int v = e[i].v;
if(v == fa) continue ;
dfs(v, u);
for(short s = min(sz[v] + sz[u], (int) m); s >= 0; s --)
for(short a = 1; a <= n; a ++)
t[s][a] = n + 1;
for(short su = min(sz[u], m); su >= 0; su --) {
for(short sv = min(sz[v], m); sv >= 0; sv --) {
short mv = n + 1;
for(int a = dl[v]; a <= dr[v]; a ++) mv = min(mv, dp[v][sv][pos[a]]);
for(int a = 1; a <= n; a ++) {
t[su + sv][a] = min((int) t[su + sv][a], dp[u][su][a] + dp[v][sv][a]);
if(a < dl[v] || a > dr[v]) {
t[su + sv][pos[a]] = min((int) t[su + sv][pos[a]], dp[u][su][pos[a]] + mv);
}
}
}
}
sz[u] += sz[v];
for(short s = min(sz[u], m); s >= 0; s --)
for(short a = 1; a <= n; a ++)
dp[u][s][a] = t[s][a];
}
}
int main() {
scanf("%hd%d", &n, &x); clr();
for(int i = 1; i <= n; i ++) {
scanf("%hd", w + i);
m += w[i];
}
for(int u, v, w, i = 1; i < n; i ++) {
scanf("%d%d%d", &u, &v, &w);
add(u, v, w); add(v, u, w);
}
for(int i = 1; i <= n; i ++) dfs0(dis[i], i);
for(int i = 0; i <= n; i ++)
for(int j = 0; j <= n; j ++)
for(int k = 0; k <= n; k ++)
dp[i][j][k] = n + 1;
dfs1(1); dfs(1);
short ans = n + 1;
for(int i = 1; i <= n; i ++)
ans = min(ans, dp[1][m][i]);
printf("%hd\n", ans > n ? -1 : ans);
return 0;
}

「CF375E」Red and Black Tree「树形DP」的更多相关文章

  1. 「树形结构 / 树形DP」总结

    Codeforces 686 D. Kay and Snowflake 要求$O(n)$求出以每个节点为根的重心. 考虑对于一个根节点$u$,其重心一定在[各个子树的重心到$u$]这条链上.这样就能够 ...

  2. HDU5834 Magic boy Bi Luo with his excited tree(树形DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...

  3. BZOJ-3227 红黑树(tree) 树形DP

    个人认为比较好的(高端)树形DP,也有可能是人傻 3227: [Sdoi2008]红黑树(tree) Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1 ...

  4. Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

    题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...

  5. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  6. 「树形DP」洛谷P2607 [ZJOI2008]骑士

    P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...

  7. 「HAOI2015树上染色」「树形DP」

    其实我还不大会树形DP 此题就当练手叭,缕一下思路就好 题目链接 BZOJ4033 题目大意就是给一棵树,对一部分点染成黑色,剩下的为白色,问所有同色点距离之和....... 简明扼要的题意,然额我不 ...

  8. NFLSOJ #10317. -「2020联考北附2」三千世界(找等价表达+树形 dp)

    题面传送门 出题人可能原本感觉没啥难度的 T2 竟然变成了防 AK 题,奇迹奇迹( 首先带着这个 \(\max\) 肯定不太好处理,考虑找出 \(f(S)\) 的等价表达.我们考虑以 \(1\) 为根 ...

  9. HDU 6035---Colorful Tree(树形DP)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

随机推荐

  1. Java基础IO类之File类

    大三了,目前基础太差了,重新学习过!代码如下,里面都有详细的解释每一行代码代表的意思~ package IODemo; import java.io.File; import java.io.File ...

  2. centos7安装oracle11g(根据oracle官方文档安装,解决图形界面安装问题)

    一.系统及安装包 操作系统:centos 7.4 oracle版本:oracle 11g r2 二.centos环境配置 安装数据库所需要的软件包 [root@localhost data]# yum ...

  3. win10环境下,让所有程序都以管理员身份运行的办法

    记录下,备查! 打开gpedit.msc组策略编辑. 左侧依次找到:计算机配置->Window设置->安全设置->本地策略->安全选项 然后再右侧找到:用户账户控制:以管理员批 ...

  4. Django2.0 分页的应用

    #分页例子from django.core.paginator import Paginatordef blog_list(request):      blog_all_list = models. ...

  5. MySQL性能测试调优

    MySQL性能测试调优 操作系统 基本操作 查看磁盘分区mount选项 $ mount 永久修改分区mount选项(系统重启后生效) 修改文件 /etc/fstab 中对应分区的mount optio ...

  6. vue 后台管理系统菜单权限管理

    来自:https://www.cnblogs.com/fqh123/p/11094296.html 侵删 login登录方法 login() { if (!this.username) { retur ...

  7. 软件自带依赖库还是共享对象库/为什么linux发行版之间不能有一个统一的二进制软件包标准

    接前文:Linux软件包(源码包和二进制包)及其区别和特点 在前文,我们知道了linux软件包分为源码包和二进制包两种方式,而不同的发行版之间又有着自己的二进制打包格式. 首先,软件运行依赖着各种各样 ...

  8. mamcached+(magent+keepalived高可用)搭建及理论概述

    目录 一.理论概述 工作流程 二.部署 环境 环境概述 部署 三.测试 四.总结 一.理论概述 Memcached服务器端与PHP-Memcache客户端安装配置_服务器应用_Linux公社-Linu ...

  9. linux 的GUNB修复问题

    1.意外断电,kali linux 虚拟机没有正常关机的时候 , 突然断电之后重启电脑之后,kali linux 直接黑屏了无法进入系统.如下面的界面 光标一直在闪烁. 这里可以使用 快捷键 同时按住 ...

  10. centos 中的vsftpd 配置

    一.安装vsftpd 1.1 检查系统是否已经安装过vsftpd了 [root@localhost /]# rpm -aq vsftpd 如果返回结果显示: vsftpd--.el7.x86_64 # ...