题目大意:
  给你一棵带边权的树,每个结点可能是红色或者黑色,你可以交换若干个点对使得任意一个红点到达与其最近的黑点的距离小于等于m。

思路:
  动态规划。
  f[i][j][k]表示以i为根的子树中,连向结点j,子树中已经确定有k个是黑点所需要的最小交换次数。
  best[i][k]表示以i为根的子树,已经确定有k个是黑点所需要的最小交换次数。
  设当前根为x,子结点为y,连向结点i,总共确定了k个黑点,新确定了l个黑点,转移方程为:
  f[x][i][k]=min(min{f[x][i][k-l]+best[y][l]},min{f[x][i][k-l+1]+f[y][i][l]-!col[i]});
  当然要判断新连向的点与当前根的距离,这可以事先跑一遍O(n^3)的Floyd。
  最后会被卡内存,据lyx介绍,由于n<=500,可以用uint16卡过去。

 #include<cstdio>
#include<vector>
typedef unsigned short uint16;
inline int getint() {
register char ch;
while(!__builtin_isdigit(ch=getchar()));
register int x=ch^'';
while(__builtin_isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
template<typename _T1,typename _T2>
inline _T1 min(const _T1 &a,const _T2 &b) {
return a<b?a:b;
}
template<typename _T1,typename _T2>
inline _T1 max(const _T1 &a,const _T2 &b) {
return a>b?a:b;
}
const uint16 inf=~;
const uint16 N=;
bool col[N];
uint16 n,s;
int m;
int dis[N][N];
std::vector<uint16> e[N];
inline void add_edge(const uint16 &u,const uint16 &v,const int &w) {
e[u].push_back(v);
e[v].push_back(u);
dis[u][v]=dis[v][u]=w;
}
uint16 f[N][N][N],best[N][N],size[N];
void dfs(const uint16 &x,const uint16 &par) {
for(uint16 i=;i<e[x].size();i++) {
const uint16 &y=e[x][i];
if(y==par) continue;
dfs(y,x);
}
for(register uint16 i=;i<=n;i++) {
if(dis[x][i]>m) continue;
size[x]=;
f[x][i][]=!col[i];
for(register uint16 j=;j<e[x].size();j++) {
const uint16 &y=e[x][j];
if(y==par) continue;
for(register uint16 k=min(s,size[x]+size[y]);;k--) {
uint16 tmp=inf;
for(register uint16 j=max(k-size[x],);j<=min(k,size[y]);j++) {
tmp=min(tmp,f[x][i][k-j]+best[y][j]);
}
for(register uint16 j=max(k-size[x],)+;j<=min(k,size[y]);j++) {
tmp=min(tmp,f[x][i][k-j+]+f[y][i][j]-!col[i]);
}
f[x][i][k]=tmp;
if(!k) break;
}
size[x]+=size[y];
}
}
for(register uint16 i=;i<=s;i++) {
best[x][i]=inf;
for(register uint16 j=;j<=n;j++) {
best[x][i]=min(best[x][i],f[x][j][i]);
}
}
}
int main() {
n=getint(),m=getint();
for(register uint16 i=;i<=n;i++) {
s+=(col[i]=getint());
}
__builtin_memset(dis,0x3f,sizeof dis);
for(register uint16 i=;i<n;i++) {
const uint16 u=getint(),v=getint();
const int w=getint();
add_edge(u,v,w);
}
for(register uint16 k=;k<=n;k++) {
for(register uint16 i=;i<=n;i++) {
for(register uint16 j=;j<=n;j++) {
dis[i][j]=i==j?:min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
__builtin_memset(f,0xff,sizeof f);
__builtin_memset(best,0xff,sizeof best);
dfs(,);
__builtin_printf("%d\n",best[][s]==inf?-:best[][s]);
return ;
}

[CodeForces-375E]Red and Black Tree的更多相关文章

  1. [CC-BLREDSET]Black and Red vertices of Tree

    [CC-BLREDSET]Black and Red vertices of Tree 题目大意: 有一棵\(n(\sum n\le10^6)\)个结点的树,每个结点有一种颜色(红色.黑色.白色).删 ...

  2. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)

    codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  3. codeforces 812E Sagheer and Apple Tree(思维、nim博弈)

    codeforces 812E Sagheer and Apple Tree 题意 一棵带点权有根树,保证所有叶子节点到根的距离同奇偶. 每次可以选择一个点,把它的点权删除x,它的某个儿子的点权增加x ...

  4. codeforces 220 C. Game on Tree

    题目链接 codeforces 220 C. Game on Tree 题解 对于 1节点一定要选的 发现对于每个节点,被覆盖切选中其节点的概率为祖先个数分之一,也就是深度分之一 代码 #includ ...

  5. BNUOJ 26229 Red/Blue Spanning Tree

    Red/Blue Spanning Tree Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on HDU. ...

  6. Codeforces E. Alyona and a tree(二分树上差分)

    题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. CF375E Red and Black Tree(线性规划)

    CF375E Red and Black Tree(线性规划) Luogu 题解时间 很明显有一个略显复杂的 $ n^3 $ dp,但不在今天讨论范围内. 考虑一些更简单的方法. 设有 $ m $ 个 ...

  8. codeforces 342E :Xenia and Tree

    Description Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes i ...

  9. Codeforces 379 F. New Year Tree

    \(>Codeforces \space 379 F. New Year Tree<\) 题目大意 : 有一棵有 \(4\) 个节点个树,有连边 \((1,2) (1,3) (1,4)\) ...

  10. codeforces 399B. Red and Blue Balls 解题报告

    题目链接:http://codeforces.com/problemset/problem/399/B 题目意思:给出 n 个只由 R 和 B 组成的字符串(由上到下排列,相当于栈),问最多可以操作多 ...

随机推荐

  1. CodeForces - 1015D

    There are nn houses in a row. They are numbered from 11 to nn in order from left to right. Initially ...

  2. 零基础讲解JavaScript函数

    一 JavaScript函数1 什么是函数  函数是一组代码(指令)的集合,通常用来完成某个单一的功能.(书的目录和章节,电视剧剧集的名称等)2 为什么要使用函数  2.1 把复杂程序划分成不同的功能 ...

  3. ThinkPHP的运行流程-1

    我在index\Lib\Action\目录下新建了一个ShowAction.class.php文件.ps:该目录是控制器的目录. 然后这个文件中继承了action这个类.代码如下: 1 2 3 4 5 ...

  4. python并发编程之asyncio协程(三)

    协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...

  5. hdu 4347 The Closest M Points (kd树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说, ...

  6. Django项目上传到AWS服务器上

    EC2是亚马逊(Amazon.com)提供的弹性云计算服务:Apache是一个跨平台的Web服务器端软件,可以使Python.PHP.Perl等语言编写的程序运行在服务器上:Django是一个Web程 ...

  7. 查找网页元素对应的js代码

    按F12打开调试窗口,切换到Sources选项卡,最右边的Event Listener Breakpoints里勾选Mouse下的mouseover即可,当鼠标移动到图片上时触发mouseover事件 ...

  8. 【前端笔记】浅谈js继承

    我们先想想我们用js最后要怎样实现面向对象的编程.事实上我们必须用上原型链这种东西. 我们的父类superType有属性和方法,并且一些能被子类subType继承,一些能被覆盖,但是丝毫不会影响到父类 ...

  9. 【hdoj_1042】N!(大数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1042 题目说明待求阶乘的数最大为10000,而10000!的位数为35660(这个数是上网查的),所以已经 ...

  10. cocos2dx2.x 创建项目

    cocos2d-x下载地址:http://www.cocos2d-x.org/download 2.0之后的创建项目比较easy了 第一步,首先 cd cocos2d-x-2.2.1/tools/pr ...