题目链接:https://vjudge.net/problem/POJ-1155

题意:给定一颗以1为根的边权树,有n个结点,其中m个叶子结点,每个叶子结点有一个价值。要求从m个叶子结点中选最多的结点,费用是从根节点到叶子结点的边权和,价值是所有选中的叶子结点价值和。

思路:

  树上分组背包。用dp[u][j]表示对于结点u的子树,选j个叶子结点的最大利润,即价值-花费。因为对u的每个子结点v1,v2,v3,在v1的子树中最多选择一种方案,不可能重叠选择,所以是分组背包。先处理出num[u],表示结点u的子树中叶子结点的个数。

  那么对于叶子结点u:dp[u][j]=a[u](a[u]是叶子结点u的价值)

    对于非叶子结点u:dp[u][j]=max(dp[u][j] , dp[u][j-k]+dp[v][k]-len),其中j是最大容量,k是枚举的容量。

  dp数组初始化为负无穷,因为一条利润为负数的方案在后面也可以和另一条利润正的方案合并,最终利润仍为正。

#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=;
const int ninf=0xcfcfcfcf;
int n,m,head[maxn],a[maxn],cnt,dp[maxn][maxn],num[maxn]; struct node{
int v,w,nex;
}edge[maxn]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u){
if(!head[u]){
dp[u][]=a[u];
num[u]=;
return;
}
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
dfs(v);
num[u]+=num[v];
}
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
for(int j=num[u];j>=;--j)
for(int k=;k<=min(j,num[v]);++k)
if(dp[u][j-k]!=ninf&&dp[v][k]!=ninf)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-edge[i].w);
}
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
dp[i][j]=ninf;
for(int i=;i<=n-m;++i){
int k,t1,t2;
scanf("%d",&k);
for(int j=;j<=k;++j){
scanf("%d%d",&t1,&t2);
adde(i,t1,t2);
}
}
for(int i=n-m+;i<=n;++i)
scanf("%d",&a[i]);
dfs();
for(int i=m;i>=;--i)
if(dp[][i]>=){
printf("%d\n",i);
break;
}
return ;
}

poj1155 TELE (树上分组背包)的更多相关文章

  1. poj1155 TELE (树上的背包)

    题目链接:http://poj.org/problem?id=1155 题意:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中间节点表示中转站,每条树边有权值.现在要在电视台 ...

  2. hdoj1011(树上分组背包)

    题目链接:https://vjudge.net/problem/HDU-1011 题意:给定一颗树,每个结点有两个属性,即花费V和价值w,并且选择子结点时必须选择父结点,求总花费不超过m的最大价值. ...

  3. 【题解】洛谷P1273 有线电视网(树上分组背包)

    次元传送门:洛谷P1273 思路 一开始想的是普通树形DP 但是好像实现不大好 观摩了一下题解 是树上分组背包 设f[i][j]为以i为根的子树中取j个客户得到的总价值 我们可以以i为根有j组 在每一 ...

  4. 洛谷P1273 有线电视网 树上分组背包DP

    P1273 有线电视网 )逼着自己写DP 题意:在一棵树上选出最多的叶子节点,使得叶子节点的值 减去 各个叶子节点到根节点的消耗 >= 0: 思路: 树上分组背包DP,设dp[u][k] 表示 ...

  5. 洛谷P1273 有线电视网 (树上分组背包)

    洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...

  6. 洛谷 P1273 有线电视网 && caioj 1109 树形动态规划(TreeDP)4:比赛转播(树上分组背包总结)

    从这篇博客往前到二叉苹果树都可以用分组背包做 这依赖性的问题,都可以用于这道题类似的方法来做 表示以i为根的树中取j个节点所能得的最大价值 那么每一个子树可以看成一个组,每个组里面取一个节点,两个节点 ...

  7. 洛谷P1273 有线电视网 【树上分组背包】

    题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...

  8. poj1947(树上分组背包)

    题目链接:https://vjudge.net/problem/POJ-1947 题意:给定一棵树,求得到一个结点数为p最少删多少条边. 思路: 明显的树形dp,分组背包.用dp[u][j]表示在结点 ...

  9. [POJ1155]TELE(树形背包dp)

    看到这道题的第一眼我把题目看成了TLE 哦那不是重点 这道题是树形背包dp的经典例题 题目描述(大概的): 给你一棵树,每条边有一个cost,每个叶节点有一个earn 要求在earn的和大于等于cos ...

随机推荐

  1. QueryList之flatten方法

    正确用法: $data = $ql->get($url)->query()->getData();$data = $data->flatten()->all(); 注意: ...

  2. Java进阶知识13 Hibernate查询语言(HQL),本文以hibernate注解版为例讲解

    1.简单概述 1.1. 1) SQL:面向的是数据库 select * from tableName;2) HQL查询(Hibernate Query language): hibernate 提供的 ...

  3. Cogs 728. [网络流24题] 最小路径覆盖问题

    [网络流24题] 最小路径覆盖问题 ★★☆ 输入文件:path3.in 输出文件:path3.out 评测插件 时间限制:1 s 内存限制:128 MB 算法实现题8-3 最小路径覆盖问题(习题8-1 ...

  4. python 3元运算符

    >>> ) >>> ) >>>

  5. Mybatis源码学习之DataSource(七)_2

    接上节数据源,本节我们将继续学习未完成的部分,包括无连接池情况下的分析.为什么使用连接池.及mybatis连接池的具体管理原理 不使用连接池的UnpooledDataSource 当 的type属性为 ...

  6. 预处理、const、static与sizeof-static有什么作用(至少说出2个)

    1:在C语言中,关键字static有3个明显的作用: (1)在函数体,一个被声明为静态的变量在这一函数被调用的过程中维持其值不变. (2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所 ...

  7. oracle存储过程中进行分页

    create or replace procedure APP_BUSSINESS_CARD_LIST(p_in_str in varchar2,p_out_str out varchar2) is ...

  8. TensorFlow错误ValueError: No gradients provided for any variable

    使用TensorFlow训练神经网络的时候,出现以下报错信息: Traceback (most recent call last):   File "gan.py", line 1 ...

  9. Java获取当前时间及String、datetime、date相互转化

    一.获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStrin ...

  10. vs下qt的信号与槽实现

    实现主窗口中Add按钮的功能, 这一部分要特别注意,除了实现功能代码外,还需自己手动添加一些其他的代码(Qt Creator可以自动添加). 我们需要在2个地方添加代码. 第1个是在addressbo ...