题目大意:
  给你一棵带边权的树,每个结点可能是红色或者黑色,你可以交换若干个点对使得任意一个红点到达与其最近的黑点的距离小于等于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. Spring Tool Suite 配置和使用

    Spring Tool Suite使用 1.下载地址: http://spring.io/tools 2.配置字符编码:UTF-8 默认的编码是ISO-8859-1的西欧文字编 1.windows-- ...

  2. 生成验证码tp

    js里拼接随机数 页面上链接 去掉后缀名

  3. linux系统cpu使用100%的命令

    for i in `seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l)`; do dd if=/dev/zero of=/d ...

  4. C/C++——[04] 语句

    在 C/C++语言中,语句以“ :”结束.某些情况下,一组语句在一起共同完成某一特定的功能,可以将它们用大括号括起来.我们称之为语句组.语句组可以出现在任何单个语句出现的地方. 1. 分支语句 一般情 ...

  5. 如何将qlv格式的腾讯视频转换为mp4格式

    一般来说,每个视频网站都会有自己的视频播放格式,如优酷的KUX.爱奇艺的QSV和腾讯的QLV等. 但是大家知道,优酷是有转码功能的,而就目前来说腾讯视频还没有转码功能,下面是将qlv格式的腾讯视频转换 ...

  6. HDU 4300 Clairewd’s message(KMP+思维)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300 题目大意:题目大意就是给以一段字符xxxxzzz前面x部分是密文z部分是明文,但是我们不知道是从 ...

  7. Jury Jeopardy(反向模拟)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAy8AAAI7CAIAAABqfzNeAAAgAElEQVR4nOy9e2AU1d3/f2ov07q166

  8. linux中$的各种含义

    我们先写一个简单的脚本,执行以后再解释各个变量的意义   # touch variable # vi variable   脚本内容如下:   #!/bin/sh echo "number: ...

  9. MVC – 4.mvc初体验(1)

    1.MVC请求模式 2.MVC简单请求流程图 展开 折叠 3.返回string的mvc方法 展开 折叠 4.加载视图的方法

  10. WERTYU(UVa10082)

    C++ 11 代码如下: #include<iostream> using namespace std; const char s[] = { "`1234567890-=QWE ...