题目大意:
  给你一棵带边权的树,每个结点可能是红色或者黑色,你可以交换若干个点对使得任意一个红点到达与其最近的黑点的距离小于等于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. NYOJ 1063 生活的烦恼 (二叉树)

    题目链接 描述 生活的暑假刚集训开始,他要决心学好字典树,二叉树,线段树和各种树,但生活在OJ上刷题的时候就遇到了一个特别烦恼的问题.那当然就是他最喜欢的二二叉树咯!题目是这样的:给你一颗非空的二叉树 ...

  2. python初步学习-面向对象之 类(二)

    方法重写 如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法: #!/usr/bin/env python #coding:utf8 class Parent: def myMeth ...

  3. c语言学习笔记.关键字.存储类型关键字等

    关键字const 1.修饰变量. 修饰的对象为常量,只读. 2.修饰指针. const 也可以和指针变量一起使用,这样可以限制指针变量本身,也可以限制指针指向的数据. const 离变量名近就是用来修 ...

  4. ProxySQL(MGR)部署故障:'sys.gr_member_routing_candidate_status' doesn't exist

    ProxySQL(MGR) 故障排查: 故障现象:runtime_mysql_servers节点状态offline_hostgroup(本案例为15) 日志关键信息: [WARNING] Group ...

  5. angular项目中使用Primeng

    1.第一步把依赖添加到项目中 npm install primeng --save npm install @angular/animations --save npm install font-aw ...

  6. Jinja2 及 render_template 的深度用法

    是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...

  7. POJ 1392 Ouroboros Snake(数位欧拉)

    题目链接:http://poj.org/problem?id=1392 题目大意:题意看的我头痛,其实跟HDU2894差不多,但是这题要求输出这条路径上第k个数,而不是输出路径. 解题思路:也跟HDU ...

  8. Numpy narray对象的属性分析

    参考官方文档链接: narray是Numpy的基本数据结构,本文主要分析对象的属性(可通过.进行访问) 1:导入numpy: import numpy as np 2:初始化narray对象: > ...

  9. 解决IE的背景颜色透明子元素不透明问题

    假设背景为黑色,70%半透明,对需要半透明的层用如下CSS background-color: #000000; /* background color for IE */ filter: alpha ...

  10. ASP.NET WebAPI 06 HttpMessageHandler管道

    HttpMessageHandler管道 在Web API的中,微软为了更好的进行架构扩展,采用的了一套管道设计----HttpMessageHander(其实WCF也有类似架构). 在整个管道中的头 ...