首页 > 其他分享 >树形DP依赖背包 洛谷 P2015 二叉苹果树

树形DP依赖背包 洛谷 P2015 二叉苹果树

时间:2023-02-07 17:01:00浏览次数:46  
标签:head 洛谷 int P2015 edge DP include 节点 dp


题目描述

有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

2   5

 \ /

  3   4

   \ /

    1

现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

给定需要保留的树枝数量,求出最多能留住多少苹果。

输入输出格式

输入格式:
 

第1行2个数,N和Q(1<=Q<= N,1<N<=100)。

N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。

每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

每根树枝上的苹果不超过30000个。

输出格式:
 

一个数,最多能留住的苹果的数量。

输入输出样例

输入样例#1 复制

5 2

1 3 1

1 4 10

2 3 20

3 5 20

输出样例#1 复制

21

算法分析:

 树形依赖背包的入门题,参考解析:​​选课​​

但与上一题有所不同,

1.这题明确给出根节点为1,所以不会是上一题的无根树

2.父节点和子结点不像上一题一样标准的给出,所以每一个结点就没有了明确的值。

3.这题要求删边对应上一题删点数目+1

这题遇上题一模一样,但是这题目没给标准的给你父节点和子节点,但在后面给你一个价值,这时候你不确定子节点是谁,所以值不能想上一题一样直接复制子节点,所以vextor就不好入手了,所以建树时要注意。

这就需要完整的链式向前星,需要保存边的值,在建好树后,赋值给对应的子节点。

推荐代码实现:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int N=310;
struct node
{
int v;///终端点
int next;///下一条同样起点的边号
int w;///权值
}edge[N*2];///无向边,2倍
int head[N];///head[u]=i表示以u为起点的所有边中的第一条边是 i号边
int tot; ///总边数
int minn;
void add(int u,int v,int w)
{
edge[tot].v=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m;
int dp[N][N],val[N];
void dfs(int u,int fa)
{
//dp[u][1]=val[u];///选一个肯定选自己这个结点
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(fa==v) continue; ///如果下一个相邻节点就是父节点,则证明到底层了,开始递归父节点的兄弟节点
dp[v][1]=edge[i].w; ///每一个结点的赋值

dfs(v,u);

for(int j=m;j>0;j--) ///背包容量
///下面这个循环必须是k<j结束,不能取等号,因为至少需要留一个点来取u点
for(int k=0;k<j;k++) ///选择用户
{
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
}
}

}
int main()
{
while(~scanf("%d%d",&n,&m))
{

memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
tot=0;


for(int i=1;i<n;i++)
{
int u,w,v;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);///注意题目给出第一个不一定是父亲结点
}

m+=1; ///虚结点加1,删n条边相当于删除n个点
dfs(1,-1);

printf("%d\n",dp[1][m]);
}

return 0;
}

我一开始做的代码

代码实现:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int N=110;
struct node
{
int v;///终端点
int next;///下一条同样起点的边号
int w;///权值
}edge[N*2];///无向边,2倍
int head[N];///head[u]=i表示以u为起点的所有边中的第一条边是 i号边
int tot; ///总边数
void add(int u,int v,int w)
{
edge[tot].v=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m;
int dp[N][N];
///dp[i][j]表示节点i保留j个枝条的所剩苹果最大值
int dfs(int u,int fa)
{
int num=0; ///num表示u节点的子节点数目
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v= edge[i].v;
if(fa==v) continue; ///如果下一个相邻节点就是父节点,则证明到底层了,开始递归父节点的兄弟节点
num+=dfs(v,u)+1;
for(int j=min(num,m);j>=1;j--) ///注意删除有限制
for(int k=min(j-1,num);k>=0;k--)
{
dp[u][j]=max(dp[u][j],dp[u][j-k-1]+dp[v][k]+edge[i].w);
}
}
return num;
}

int main()
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
tot=0;

for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dfs(1,-1);
printf("%d\n",dp[1][m]);
return 0;
}

 

标签:head,洛谷,int,P2015,edge,DP,include,节点,dp
From: https://blog.51cto.com/u_14932227/6042481

相关文章

  • 树形DP (cf 219D Choosing Capital for Treeland)
    题意翻译题目描述Treeland国有n个城市,这n个城市连成了一颗树,有n-1条道路连接了所有城市。每条道路只能单向通行。现在政府需要决定选择哪个城市为首都。假如城市i成为了首都......
  • 树形DP+概率DP
    动态规划报告树形dp树形DP,即在树上进行的DP。由于树固有的递归性质,树形DP一般都是递归进行的。一般需要在遍历树的同时维护所需的信息以一道题目为例2022CCPC桂林......
  • PHP远程操纵WordPress的方法(流程剖析)
    一直想写一个给wordpress群发文章的应用,这样我就能自动采集文章,然后写个脚本自动发送文章了,哈哈。虽然用python干这种事情貌似更加擅长,但是我想做个web界面访问该应用,而pyth......
  • DPU,PPM,DPMO,DPO,RTY-质量工程师不可不知的度量指标
    质量工程师经常都会接触到一些术语,其中最常见而又最易令他们混淆的,应该就是DPU、PPM(DPPM)、DPMO、DPO和RTY了。其实在进行质量改善或者六西格玛项目时,准确地测量过程性能指标......
  • 种类并查集 洛谷 P2024 食物链
    题目描述动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B,B吃C,C吃A。现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道......
  • HDU/HDOJ 2067 小兔的棋盘 DP/卡特兰数
    HDU/HDOJ2067小兔的棋盘小兔的棋盘TimeLimit:1000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):12782    Acce......
  • POJ 3276 Face The Right Way/洛谷P2882 [USACO07MAR]面对正确的方式 反转
    题目描述FarmerJohnhasarrangedhisN(1≤N≤5,000)cowsinarowandmanyofthemarefacingforward,likegoodcows.Someofthemarefacingbackward,th......
  • 2019南昌网络赛 I. Max answer(DP或者单调栈+思维)
    Alicehasamagicarray.Shesuggeststhatthevalueofaintervalisequaltothesumofthevaluesintheinterval,multipliedbythesmallestvalueinthein......
  • 51nod 2484 小b和排序(DP)
    小b有两个长度都为n的序列A,B。现在她需要选择一些i,然后交换A[i]和B[i],使得A和B都变成严格递增的序列。你能帮小b求出最少交换次数吗?输入保证有解。 收起输入第一行输入一......
  • 论文翻译:2022_Time-Shift Modeling-Based Hear-Through System for In-Ear Headphones
    论文地址:基于时移建模的入耳式耳机透听系统引用格式:摘要透传(hear-through,HT)技术是通过增强耳机佩戴者对环境声音的感知来主动补偿被动隔离的。耳机中的材料会减......