ural 1018 二叉苹果树

/*
二叉苹果树(树形dp)
f[root, m]=f[root.left, i]+f[root.right, m-i-1]+v[root];
*/
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int M=105;
struct linklist
{
	int s;
	int val;
	linklist *next;
};
struct tree
{
	int val;
	int l;
	int r;
};
tree t[M];
linklist a[M];
int rmb[M][M];
int n, m;
int vis[M];
stack<int>s1;
void debug()
{
	/*for (int i=1; i<=n; i++)
	{
		printf("i:%d  val:%d  l:%d   r:%d\n", i, t[i].val, t[i].l, t[i].r);
	}*/
	for (int i=1; i<=n; i++)
	{
	 for (int j=0; j<=m+1; j++)
	 printf("%d ", rmb[i][j]);
	 printf("\n");
    }
}
void linklist_reset()
{
	for(int i=1; i<=n; i++)
	{
		a[i].next=NULL;
		a[i].s=i;
		a[i].val=0;
	}
}
int treedp(int root, int k)
{
	if (root==0) return 0;
	if (k==0) return 0;
	if (rmb[root][k]!=0) return rmb[root][k];
    int temp=0;
	for (int i=0; i<=k-1; i++)
	{
		int l=t[root].l;
		int r=t[root].r;
		int ml=treedp(l, i);
		int mr=treedp(r, k-i-1);
		temp=max(ml+mr, temp);
	}
	rmb[root][k]=temp+t[root].val;
	return rmb[root][k];
}
void build()
{
	t[1].val=0;
	vis[1]=1;
	s1.push(1);
	while (!s1.empty())
	{
		int v=s1.top();
		s1.pop();
		for(linklist *j=a[v].next; j!=NULL; j=j->next)
		{
			int temp=j->s;
		    if (!vis[temp])
		     {
		     	if (t[v].l==0) t[v].l=temp;
			    else t[v].r=temp;
		    	t[temp].val=j->val;
			    s1.push(temp);
			    vis[temp]=1;
			}
		}
	}	
}
void solve()
{
	build();
	
	int ans=treedp(1,m+1);
	printf("%d", ans);
	
}
void insert(linklist &x, int y, int val)
{
	linklist *t;
	t=new(linklist);
	t->s=y;
	t->val=val;
	t->next=x.next;
	x.next=t;
}
void init()
{
	memset(rmb, 0, sizeof(rmb));
	memset(vis, 0, sizeof(vis));
	scanf("%d %d", &n, &m);
	linklist_reset();
	for (int i=1; i<n; i++)
	{
		int x, y, val;
		scanf("%d %d %d", &x, &y, &val);
		insert(a[x], y, val);
		insert(a[y], x, val);
	} 
}
int main()
{
	init();
	solve();
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值