【LuoguP1273有线电视网】树形依赖背包
参考论文http://wenku.baidu.com/view/8ab3daef5ef7ba0d4a733b25.html
参考一篇写的很好的博文http://www.cnblogs.com/GXZC/archive/2013/01/13/2858649.html
题目链接http://www.luogu.org/problem/show?pid=1273

首先确定泛化物品的定义:价值随着体积变化的物体,如01背包中的f[i](体积为i时的最大价值最f[i])。
泛化物品+普通物品:
还是01背包,我们是怎么在泛化物品f[i]中加入一个体积为v,价值为w的普通物品的?
f[i]=max(f[i],f[i-v]+w);
O(n)解决。
分析题目:可以看作是叶子节点的v=1,非叶子节点的v=0,w=父亲到该点的费用*(-1)+该点的money。就是一个树形依赖模型,每个节点是一个物品。
设f[i][j]表示dfs序小于等于节点i的所有节点(物品)中,体积为j时的最大价值。
设s为i的一个孩子。
则f[i]管理的范围为红色圈,f[s]管理的范围为蓝色圈。

从上往下(父亲-->孩子)dfs时,先让f[s]=f[i](s继承i的全部信息)
强制让f[s]必须选择s,然后往下对s进行dp。
让f[s]必须选普通物品s是因为选择了s才能选s的孩子:f[s]=f[i]; f[s][j]=max(f[s][j],f[s][j-v]+w);就是说,f[s]=f[i]+物品s
如果不是选择孩子之前必须选择父亲:f[s]=max(f[i],f[i]+物品s)
回溯(孩子-->父亲)时:将f[s]与f[i]合并。
泛化物品的并: 因为两个泛化物品之间存在交集,所以不能同时两者都取,那么我们就需要求 泛化物品的并,对同一体积,我们需要选取两者中价值较大的一者,效率 O(C)。
F[j] = max{ F1[j] , F2[j] } (C>=j>=0)

我的代码以及注释:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N=,Inf=(int)1e9;
struct node{
int x,y,d,next;
}a[*N];
int len,n,m;
int first[N],v[N],w[N],f[N][N],cost[N]; int maxx(int x,int y){return x>y ? x:y;} void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=first[x];first[x]=len;
} void init()
{
len=;
memset(first,,sizeof(first));
for(int i=;i<=n-m;i++)
{
int k,x,d;
scanf("%d",&k);
for(int j=;j<=k;j++)
{
scanf("%d%d",&x,&d);
ins(i,x,d);ins(x,i,d);
}
}
for(int i=n-m+;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=n-m;i++) v[i]=;
for(int i=n-m+;i<=n;i++) v[i]=;
} void dfs(int x,int fa)
{
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y!=fa)
{
if(y>=n-m+) cost[y]=-a[i].d+w[y];
else cost[y]=-a[i].d;
dfs(y,x);
}
}
} void dp(int x,int fa)
{
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y,V=v[y],W=cost[y];
if(y==fa) continue; for(int j=;j<=n;j++) f[y][j]=f[x][j];
dp(y,x); // 泛化物品(f[x])加普通物品(节点y:V=v[y],W=cost[y])
// 初始化f[y]:f[y][j]=max(f[y][j],f[y][j-V]+W); // 泛化物品(f[x])与泛化物品(f[y])合并(f[x]与f[y]存在交集)
// f[x][j]=maxx(f[x][j],f[y][j+V]);
for(int j=V;j<=n-V;j++)
f[x][j]=maxx(f[x][j],f[y][j-V]+W);//加普通物品y应放在dp(y)后,因为f[y]是表示y可选可不选的,如果先压进去就必须选。
}
} int main()
{
freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
scanf("%d%d",&n,&m);
init();
dfs(,);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(j==) f[i][j]=;
else f[i][j]=-Inf;
dp(,);
int ans=;
for(int i=n;i>=;i--)
if(f[][i]>=) {printf("%d\n",i);return ;}
printf("0\n");
return ;
}
【LuoguP1273有线电视网】树形依赖背包的更多相关文章
- luoguP1273 有线电视网 [树形dp]
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...
- Luogu P1273 有线电视网(树形dp+背包)
P1273 有线电视网 题面 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部 ...
- BZOJ.4182.Shopping(点分治/dsu on tree 树形依赖背包 多重背包 单调队列)
BZOJ 题目的限制即:给定一棵树,只能任选一个连通块然后做背包,且每个点上的物品至少取一个.求花费为\(m\)时最大价值. 令\(f[i][j]\)表示在点\(i\),已用体积为\(j\)的最大价值 ...
- BZOJ.4910.[SDOI2017]苹果树(树形依赖背包 DP 单调队列)
BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明.与\(shadowice\)的做法还是有差异的(比如并没 ...
- bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)
菜菜推荐的“水题”虐了我一天T T...(菜菜好强强qwq~ 显然是个分数规划题,二分答案算出p[i]-mid*s[i]之后在树上跑依赖背包,选k个最大值如果>0说明还有更优解. 第一次接触树形 ...
- Gym - 100502G Outing (强连通缩点+树形依赖背包)
题目链接 问题:有n个人,最多选k个,如果选了某个人就必须选他指定的另一个人,问最多能选多少个人. 将每个人所指定的人向他连一条单向边,则每一个点都有唯一的前驱,形成的图是个基环树森林,在同一个强连通 ...
- RNQOJ [stupid]愚蠢的矿工(树形依赖背包)
题意 题目链接 Sol 树形依赖背包板子题 树形依赖背包大概就是说:对于一个点,只有选了它的父亲才能选自身 把dfs序建出来,倒过来考虑 设\(f[i][j]\)表示从第\(i\)个节点往后背包体积为 ...
- 【bzoj2427】【软件安装】tarjan缩点+树形依赖背包
(上不了p站我要死了,侵权度娘背锅) Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上, ...
- 洛谷P1273 有线电视网 (树上分组背包)
洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...
随机推荐
- 【Spring实战】----开篇(包含系列目录链接)
[Spring实战]----开篇(包含系列目录链接) 置顶2016年11月10日 11:12:56 阅读数:3617 终于还是要对Spring进行解剖,接下来Spring实战篇系列会以应用了Sprin ...
- unity3d NavMeshAgent 寻路画线/画路径
今天在群里看见有个小伙在问Game视图寻路时怎么画线 正好前几天写了个寻路,而且自己也不知道具体怎么在寻路时画线,所以决定帮帮他,自己也好学习一下 在百度查了一下资料,直接搜寻路画路径.寻路画线... ...
- 「暑期训练」「基础DP」 Monkey and Banana (HDU-1069)
题意与分析 给定立方体(个数不限),求最多能堆叠(堆叠要求上方的方块严格小于下方方块)的高度. 表面上个数不限,问题是堆叠的要求决定了每个方块最多可以使用三次.然后就是对3n" role=& ...
- ubuntu安装显卡驱动和cuda
NVIDIA-linux.run安装后,会出现登录页面循环,解决办法是在运行命令后加入-no-opengl-files 打开nvidia x server Settings软件,显示:You do n ...
- [整理]docker内部时区修改的两种方法
方法一 终端执行 date命令,查看宿主服务器的时区是否正确 如果正确: 执行 docker cp /etc/localtime 容器ID:/etc/localtime 将本地时间拷贝到docker内 ...
- 【转】给大家分享一下目前mlc颗粒的内存卡资料
以下信息是LZ从其它论坛上找到的TF卡也是有讲究的,一分价钱一分货 dboy99 楼主 骚(6) #1楼 2015-8-5 14:49引用Micro SD卡也叫TF卡,作为手机扩展存储空间的唯一方式用 ...
- 个人作业Week3-案例分析(201521123103 吴雅娟)
根据博客要求,写一篇个人随笔 参考来自: http://www.cnblogs.com/xinz/archive/2012/03/26/2417699.html: http://www.cnblogs ...
- php获取微信token和ticket并返回签名
jssdk.php页,主要获取token和ticket <?php /* * 微信公众号后台里获取appId和appSecret,并在公众号后台=>安全中心=>IP白名单中设置当前页 ...
- WCF 动态调用(动态创建实例接口)
很多时候,服务地址都不止一个的,这个时候就要动态去配置地址.配置Web.config,很麻烦 下面就看看怎样实现动态调用WCF. 首先看看动态创建服务对象的代码: using System; usin ...
- Android 多屏幕适配 dp和px的关系
一直以来别人经常问我,android的多屏幕适配到底是怎么弄,我也不知道如何讲解清楚,或许自己也是挺迷糊. 以下得出的结论主要是结合官方文档进行分析的https://developer.android ...