[树形DP]二叉苹果树

二 叉 苹 果 树 二叉苹果树


题目描述

有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

2 5
\ /
3 4
\ /
1


输入

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


输出

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


样例输入

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


样例输出

21


code

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int n,q,t[105][105],b[105],tr[105][105],vi[105][105];
void bu(int x)
{
	int te=0;
	for(int i=0;i<=n;++i)
	{
		if(t[x][i]!=-1)
		{
			++te;
			b[i]=t[x][i];	
			tr[x][te]=i;
			t[x][i]=t[i][x]=-1;
			bu(i);
			if(te==2)return ;
		}
	}	
}
void dfs(int x,int te){
	if(te==0)vi[x][te]=0;
	else if(tr[x][1]==0 && tr[x][2]==0)vi[x][te]=b[x];
	else
	{
		vi[x][te]=0;
		for(int i=0;i<te;++i)
		{
			if(vi[tr[x][1]][i]==0)dfs(tr[x][1],i);
			if(vi[tr[x][2]][te-i-1]==0)dfs(tr[x][2],te-1-i);
			vi[x][te]=max(vi[x][te],(vi[tr[x][1]][i]+vi[tr[x][2]][te-i-1]+b[x]));
		}
	} 
}
int main()
{	
	memset(t,-1,sizeof(t));
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n-1;i++)
	{
		int t1,t2,t3;
		scanf("%d%d%d",&t1,&t2,&t3);
		t[t1][t2]=t[t2][t1]=t3;
	}
	bu(1);
	dfs(1,q+1);
	printf("%d",vi[1][q+1]);
	return 0;
}
posted @ 2020-08-15 15:21  unknown_future  阅读(63)  评论(0编辑  收藏  举报