ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【SSL_1605】&【lg_P2015】二叉苹果树

2021-05-03 20:59:16  阅读:170  来源: 互联网

标签:lg 结点 int 树枝 1605 tree num P2015 101


题目描述

有一棵苹果树,如果树枝有分叉,一定是分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个。

输出格式

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

输入输出样例

输入

5 2
1 3 1
1 4 10
2 3 20
3 5 20

输出

21

思路

先用邻接矩阵和递归建树, t r e e [ x ] [ 1 ] tree[x][1] tree[x][1]表示节点x的左节点, t r e e [ x ] [ 1 ] tree[x][1] tree[x][1]表示它的右节点。
f [ i ] [ j ] f[i][j] f[i][j]表示以第i个节点为根,保留j条树枝的最多苹果, n u m [ i ] num[i] num[i]表示子节点为 i i i的边的权值。
d f s dfs dfs序枚举 i i i,再枚举 k k k, 0 < = k < j 0<=k<j 0<=k<j,得:
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , ( f [ t r e e [ i ] [ 1 ] ] [ k ] + f [ t r e e [ i ] [ 2 ] ] [ j − k − 1 ] + n u m [ i ] ) ) f[i][j]=max(f[i][j],(f[tree[i][1]][k]+f[tree[i][2]][j-k-1]+num[i])) f[i][j]=max(f[i][j],(f[tree[i][1]][k]+f[tree[i][2]][j−k−1]+num[i]))

代码

#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
int n,q,f[101][101],x,y,a,m[101][101],e[101],tree[101][3];
void in()
{
	cin>>n>>q;
	for(int i=1;i<=100;i++) for(int j=1;j<=100;j++) m[i][j]=-1;//初始化不可少
	for(int i=1; i<n; i++)
	{
		cin>>x>>y>>a;
		m[x][y]=m[y][x]=a;//邻接矩阵
	}
}
void build(int x)//递归建树
{
	int t=1;
	for(int i=1; i<=100; i++)
	{
		if(m[x][i]>=0)
		{
			e[i]=m[x][i];
			m[x][i]=m[i][x]=-1;
			tree[x][t++]=i;
			build(i);
			if(t>2) break;
		}
	}
}
void tdp(int x,int k)
{
	if(!k) return;
	int l=tree[x][1],r=tree[x][2];
	if(!l) f[x][k]=e[x];
	else
	{
		f[x][k]=e[x];
		for(int i=0; i<k; i++)
		{
			if(!f[l][i]) tdp(l,i);
			if(!f[r][k-i-1]) tdp(r,k-i-1);
			f[x][k]=max(f[x][k],(f[l][i]+f[r][k-i-1]+e[x]));//状态转移
		}
	}
}
int main()
{
	in();
	build(1);
	tdp(1,q+1);
	cout<<f[1][q+1];
}

标签:lg,结点,int,树枝,1605,tree,num,P2015,101
来源: https://blog.csdn.net/keyixi/article/details/116380375

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有