【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 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...
随机推荐
- Hibernate-ORM:14.Hibernate中的命名查询
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述命名查询,所谓命名查询是什么呢? Hibernate中允许我们在xml,实体类,甚至注解的方式来编 ...
- 创龙DSP6748的DAC例程研究
1. 创龙DSP6748开发板驱动TL5724这个DAC,输出指定的电压值,此程序是使用 IO 口模拟 SPI 实现与 TL5724 模块的数据交互. 2. 首先是初始化PSC函数 void PSCI ...
- guacamole实现虚拟键盘
要做的事情比较简单,就是先实例化一个虚拟键盘,然后监听事件即可. js代码 //虚拟键盘数据 var a = {"language":"en_US"," ...
- JMeter学习笔记(九) 参数化3--User Defined Variables
3.User Defined Variables 1)添加用户定义的变量 2)添加变量 3)添加HTTP请求,引用变量,格式:${} 4)执行HTTP请求,察看结果树 5)用户定义的变量,优缺点: * ...
- 初识Django —Python API接口编程入门
初识Django —Python API接口编程入门 一.WEB架构的简单介绍 Django是什么? Django是一个开放源代码的Web应用框架,由Python写成.我们的目标是用Python语言, ...
- skip-grant-tables 修改linux的mysql忘记root密码
skip-grant-tables 修改linux的mysql忘记root密码 今天修改mysql中的admin用户权限,在执行update user set host =' %' where use ...
- BZOJ 4029 HEOI2015 定价 数位贪心
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4029 题意概述:对于一个数字的荒谬程度定义如下:删除其所有的后缀0,然后得到的数字长度为a ...
- servlet入门(1)
第一个servlet类 1.编写一个java类,继承HttpServlet类 2.重写doget和dopost方法 3.Servlet程序在tomcat服务器运行 第一步:找到server窗口,并新建 ...
- linux文件系统(ext2)
一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的信息.下图是一个磁盘分区格式化成e ...
- TLS协议分析
TLS协议分析 本文目标: 学习鉴赏TLS协议的设计,透彻理解原理和重点细节 跟进一下密码学应用领域的历史和进展 整理现代加密通信协议设计的一般思路 本文有门槛,读者需要对现代密码学有清晰而系统的理解 ...