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

    原文:Kali-linux设置ProxyChains ProxyChains是Linux和其他Unices下的代理工具.它可以使任何程序通过代理上网,允许TCP和DNS通过代理隧道,支持HTTP.SO ...

  2. gunicorn之日志详细配置

    gunicorn的日志配置 gunicorn的日志配置相关的常用参数有4个,分别是accesslog,access_log_format,errorlog,loglevel. accesslog:用户 ...

  3. 安全测试===CSRF攻击简介

    http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html

  4. 安装ssh-keygen

    转载自:http://www.daoan.com/forums/index.php?forumid=5&mods=topicdisplay&postid=4 sudo apt-get ...

  5. ProxySQL 排错 Max connect timeout reached while reaching hostgroup 10 after 10000ms

    ProxySQL 排错 问题分析: 在ProxySQL在集群下,因未知原因导致误测到所有节点OFFLINE_HARD,并runtime_mysql_servers表清空,从而导致前端查询无法传递到后端 ...

  6. Excel---导出与读取(大数据量)

    Excel下载 首先大数据量的下载,一般的Excel下载操作是不可能完成的,会导致内存溢出 SXSSFWorkbook 是专门用于大数据了的导出 构造入参rowAccessWindowSize 这个参 ...

  7. centos7安装完成后的一些配置

    1.打开终端 输入 sudo yum -y update 先更新软件包 2.这是输入语言 应用程序->系统工具->设置->区域和语言->+   ->汉语(中国)-> ...

  8. Unity 软件使用事项

    打开旧版工程 目前发现两种方式来触发升级程序: 1.Unity软件启动时选择旧版工程,触发更新 2.直接打开旧版工程的场景文件,触发更新   在使用中发现一种错误做法,不知道是不是共性问题,在此先记录 ...

  9. AtCoder Non-decreasing(数学思维)

    题目链接:https://abc081.contest.atcoder.jp/tasks/arc086_b 题目大意:有n个数,最多可以执行2*n次操作,每次可以选择将ai加到aj上,最终使得该序列满 ...

  10. css控制单行文本溢出

    1.溢出属性(容器的) overflow:visible/hidden(隐藏)/scroll/auto(自动)/inherit; visible:默认值,内容不会被修剪,会成现在元素框之外: hidd ...