【BZOJ3935】Rbtree

Description

给定一颗 N 个点的树,树上的每个点或者是红色,或者是黑色。
每个单位时间内,你可以任选两个点,交换它们的颜色。
出于某种恶趣味,你希望用最少的时间调整结点的颜色,使得对于每个点,离它最近的黑色点与它的距离不超过 x。

Input

输入的第一行包含整数 N 和 x(1 <= x <= 10^9)。
接下来一行 N 个整数 C1-Cn,表示结点的初始颜色。1 表示黑色,0 表示红色。
接下来 N-1 行,每行 3 个整数 ui, vi,wi(1 <= wi <= 10^9),表示点 ui 和 vi 之间存在权值为 wi的边。

Output

输出一个数表示答案;如果无解,输出 “-1”。

Sample Input

3 2
1 0 0
1 2 2
2 3 2

Sample Output

1

HINT

数据规模和约定
对于100%的数据 N<=500

题解:大神们写的都是单纯形?算了我只知道树形DP。

本题的思路和小奇挖矿相同。用f[x][a][b]表示在x的子树中放a个黑点,且距离x最近的黑点是b的最小花费(即有多少点从白点变成黑点)。转移时,对于a那维相当于树形背包,我们考虑b那维怎么转移。

如果我们想用f[y][..][c]来更新f[x][..][b],那么讨论:如果b==c,直接转移即可;如果c在y的子树中,那么用f[y][..][c]的最大值来更新f[x][..][b]即可;如果c不在y的子树中,那么我们将b换成c或者将c换成b一定不会变的更差,所以:不用转移!

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n,m,ans,cnt;
ll K;
int v[505],p[505],q[505],Q[505],siz[505],g[505][505],to[1010],next[1010],head[505];
int f[505][505][505];
ll dis[505][505],val[1010];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void dfs1(int x,int fa,int y)
{
if(y==1) p[x]=++p[0],Q[p[0]]=x;
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa) dis[to[i]][y]=dis[x][y]+val[i],dfs1(to[i],x,y);
if(y==1) q[x]=p[0];
}
void dfs2(int x,int fa)
{
int i,y,j,k,a,mn;
siz[x]=1;
for(a=1;a<=n;a++) if(a!=x&&dis[a][x]<=K) f[x][0][a]=0;
f[x][1][x]=!v[x];
for(i=head[x];i!=-1;i=next[i]) if(to[i]!=fa)
{
y=to[i],dfs2(y,x);
memset(g,0x3f,sizeof(g));
for(j=0;j<=siz[x]&&j<=m;j++) for(k=0;k<=siz[y]&&j+k<=m;k++)
{
mn=0x3f3f3f3f;
for(a=p[y];a<=q[y];a++) mn=min(mn,f[y][k][Q[a]]);
for(a=1;a<=n;a++) g[j+k][a]=min(g[j+k][a],f[x][j][a]+f[y][k][a]);
for(a=1;a<p[y];a++) g[j+k][Q[a]]=min(g[j+k][Q[a]],f[x][j][Q[a]]+mn);
for(a=q[y]+1;a<=n;a++) g[j+k][Q[a]]=min(g[j+k][Q[a]],f[x][j][Q[a]]+mn);
}
siz[x]+=siz[y];
for(j=0;j<=siz[x]&&j<=m;j++) for(a=1;a<=n;a++) f[x][j][a]=g[j][a];
}
}
int main()
{
n=rd(),K=rd();
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) v[i]=rd(),m+=v[i];
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
for(i=1;i<=n;i++) dfs1(i,0,i);
memset(f,0x3f,sizeof(f));
dfs2(1,0);
ans=1<<30;
for(i=1;i<=n;i++) ans=min(ans,f[1][m][i]);
printf("%d",ans>n?-1:ans);
return 0;
}

【BZOJ3935】Rbtree 树形DP的更多相关文章

  1. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  2. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  3. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  7. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  8. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  9. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

随机推荐

  1. 文本处理三剑客之AWK的用法

    1.awk命令简介: awk是一种可以处理数据.产生格式化报表的语言,功能十分强大. awk的工作方式是读取数据,将每一行数据视为一条记录(record)每笔记录以字段分隔符分成若干字段,然后输出各个 ...

  2. vsearch 去除重复序列和singleton 序列

    在16S数据分析中,为了减少聚类的时间,提高准确度,需要去除重复序列,而singleton序列因为没有其他的序列作为验证,可信度不是很高,也需要去除,通常情况下使用usearch 完成这2项任务,但是 ...

  3. PHPExcel正确读取excel表格时间单元格(转载)

    error_reporting(E_ALL); date_default_timezone_set('Asia/shanghai'); /** PHPExcel_IOFactory */ requir ...

  4. MyEclipse 对项目进行build path无效

    今天发现昨天从svn下载下来的项目在MyEclipse中无法build path .提示no actions available 在网上找了下,是由于.projects文件的问题,须要在当中的natu ...

  5. HBase复制

    HBase复制是一种在不同HBase部署中复制数据的方法.它能够作为一种故障恢复的方法,并提供HBase层次的高可用性.在实际应用中,比如.能够将数据从一个面向页面的集群拷贝到一个MapReduce集 ...

  6. IE6图片元素img下出现多余空白问题

    在进行页面的 DIV+CSS排版时,遇到IE6(当然有时Firefox下也会偶遇)浏览器中的图片元素img下出现多余空白的问题绝对是常见的对于该问题的解决方法 也是“见机行事”,根据原因的不同要用不同 ...

  7. 请问C#中string是值传递还是引用传递?

    https://www.cnblogs.com/xiangniu/archive/2011/08/17/2143486.html 学了这么久,终于弄明白了... 是引用传递 但是string又有值传递 ...

  8. A complete example using RAISE_APPLICATION_ERROR : raise_application_error

    from:http://www.java2s.com/Tutorial/Oracle/0480__PL-SQL-Programming/AcompleteexampleusingRAISEAPPLIC ...

  9. 《R语言入门》语言及环境简单介绍

    简单介绍 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...

  10. 对double数据类型的数据保留两位小数,并且进行四舍五入

    1.代码如下: /** * 对double数据类型的数据 保留两位小数,并且进行四舍五入 * @author Administrator */ public class Main { // 工具类 p ...