【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. 没有启动 ASP.NET State service错误的解决方法

    具体错误如下: 异常详细信息: System.Web.HttpException: 无法向会话状态服务器发出会话状态请求.请确保已启动 ASP.NET State service,并且客户端和服务器端 ...

  2. r指定位置插入一列

    y<-1:4 data1 <-data.frame(x1=c(1,3,5,7), x2=c(2,4,6,8),x3=c(11,12,13,14),x4=c(15,16,17,18)) da ...

  3. 用javascript将数据导入Excel

    网上收集的代码 <input type="button" name="out_excel" onclick="AutomateExcel();& ...

  4. e677. 模糊化图像

    This example demonstrates a 3x3 kernel that blurs an image. Kernel kernel = new Kernel(3, 3, new flo ...

  5. 基于Poco的UTF8、UTF16、GBK、Hex之间的转换

    /******Encoding.h*******/ #include "Poco/UnicodeConverter.h" #include "Poco/Exception ...

  6. chrome 版本升级到56,报错Your connection is not private NET::ERR_CERT_WEAK_SIGNATURE_ALGORITHM

    ubuntu14.04 解决方法: $ sudo apt-get install libnss3-1d ref: http://stackoverflow.com/questions/42085055 ...

  7. 分享jQuery封装好的一些常用操作

    1. 禁止右键点击 $(document).ready(function(){   $(document).bind("contextmenu",function(e){      ...

  8. jquery把int类型转换成字符串类型的方法

    jQuery中把获取的number类型数据转换成字符串类型 var val=$(“#id).val(); If(typeof val==”number”){ val+=' '; }

  9. 继承MonoBehaviour类的优缺点和相关报错

    Unity3D文档里虽然说所有脚本继承MonoBehaviour类,但如果你想自定义类,就可以不用继承MonoBehaviour,但是这个类只能调用其中的方法和属性,无法拖到场景的物体中使用. 所有从 ...

  10. linux数据盘分区以及格式化

    首先切换到root账户下  sudo -i 手动格式化 请根据以下步骤对数据盘进行分区以及格式化,并挂载分区使数据盘可用. 注:执行以下命令时,请注意修改数据盘符,可以使用”fdisk -l”查看盘符 ...