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

    <!DOCTYPE html><html lang="zh-cmn-Hans"><head><meta charset="utf ...

  2. 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)

    题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...

  3. Django之jsonp跨域请求原理

    在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题有两种方法: 一.jsonp 二.XMLHttpRequest2 ...

  4. 固定bottom,页面其它可滑动实现方案

    利用flex布局, <html> <body> <div class='container'> <div class='content'></di ...

  5. 打表找规律C - Insertion Sort Gym - 101955C

    题目链接:https://cn.vjudge.net/contest/273377#problem/C 给你 n,m,k. 这个题的意思是给你n个数,在对前m项的基础上排序的情况下,问你满足递增子序列 ...

  6. django框架<三>

    一.ORM操作  1.django orm创建数据库的方法 (1)指定连接pymysql(python3.x),先配置__init__.py import pymysql pymysql.instal ...

  7. Appium环境搭建说明(包括报错处理)

    Appium环境搭建说明 一.环境配置 前提是windows系统已安装以下软件: 1.jdk 我装的是1.8.0 2.android-sdk 3.python,3.4-3.6 5.Node.js,v8 ...

  8. u-boot界面添加命令[demo]

    目标板:2440 如何在u-boot界面中增加命令 在/common/目录下建立文件,调用执行函数do_bootm就行,然后在修改Makefile,就OK了. 比如在u-boot界面添加命令test ...

  9. SuSE Linux Supervisor的安装与使用案例

      建议使用 root 管理员账户操作 1.安装工具 1.apache 2..Net Core(dotnet-sdk-2.0) 3.Supervisor(进程管理工具,目的是服务器一开机就启动服务器 ...

  10. poj 1077(BFS预处理+康托展开)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29935   Accepted: 13029   Special ...