HDOJ The more, The Better 树形DP

算是树形DP的入门题吧。学习了一下人家的代码过的。在网上看了几种版本。果然还是dfs遍历树好啊。树形结构用指针来建的话可以省去很多麻烦。另外这题不能赤裸裸的从叶子节点更新,因为根是可以选择多个叶子的。没用完一个叶子,就必须把相应的父亲节点更新。偷笑还不错的题。

#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 222
using namespace std;

struct node
{
 	   int point;
 	   node* next;
}edge[MAXN],*ptr[MAXN];


int N,M;
int f[MAXN][MAXN];
int value[MAXN];
int edgeNum;
int max( int a,int b ){ return a>b?a:b; }

void addEdge( int father,int son )
{
 	 node *p=&edge[edgeNum++];
 	 p->point=son;
 	 p->next=ptr[father];
 	 ptr[father]=p;
}

void dfs( int cur,int deep )
{
 	node *p=ptr[cur];
 	while( p!=NULL )
 	{
	 	   for( int i=deep+1;i<=M;i++ )
	 	   		f[p->point][i]=f[cur][i-1]+value[p->point];
	 	   dfs( p->point,deep+1 );
	 	   for( int i=deep+1;i<=M;i++ )
	 	   		f[cur][i]=max( f[cur][i],f[p->point][i] );
	 	   p=p->next;
  	}
}

int main()
{
 	while( scanf( "%d %d",&N,&M ),N||M )
 	{
	 	   M++;
	 	   memset( f,0,sizeof(f) );
	 	   memset( value,0,sizeof(value) );
	 	   memset( ptr,0,sizeof(ptr) );
	 	   edgeNum=0;
		   int father,val;
	 	   for( int i=1;i<=N;i++ )
	 	   {
		   		scanf( "%d %d",&father,&val );
		   		value[i]=val;
		   		addEdge( father,i );
		   }
		   dfs( 0,1 );
		   printf( "%d\n",f[0][M] );
  	}
 	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值