hdu 1520 Anniversary party

树形dp入门,可简单理解成线性dp(数塔呗) +  一点点拓扑,

手贱的去尝试#define REP 之类的,,结果玩不好被自己死坑。(vector 从 0~size-1, 自己定义成1~size TUT)不作不死多做多死...

/*

ans=max{dp[i][0],dp[i][1]}

dp[i][0]=sum(max{dp[j][0],dp[j][1]}) 

//如果不包括i
则其子树的最大和是不包括其孩子

//或者包括其孩子两种可能下的最大和

dp[i][1]=sum(dp[j][0]) //如果包括i,则只能是不包括其孩子的最大和
*/

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;

//#define MAX(a, b) (a) > (b)? (a) : (b)

#define FOR(i, n) for(int i = 1; i <= n; i++)
#define REP(i, a, b) for(int i = a; i <= b; i++)
#define REV(i, a, b) for(int i = a; i >= b; i--)

vector<int> v[6005];
int w[6005];
int n;
bool in[6005];
int dp[6005][2];

void init()
{
	FOR(i, n)
		v[i].clear();
	memset(in, 0, sizeof(in));
	memset(dp, 0, sizeof(dp));
}

void dfs(int from)
{
	//printf("%d\n", from);
	int x = v[from].size();
	dp[from][1] = w[from];
	REP(i, 0, x-1)
	{
		int to = v[from][i];
		dfs(to);
		dp[from][0] += max( dp[to][0] , dp[to][1] );
		dp[from][1] += dp[to][0];
	}
}

int main()
{
	while(~scanf("%d", &n))
	{
		init();
		FOR(i, n)
			scanf("%d", &w[i]);
		int a, b;
		while(1)
		{
			scanf("%d%d", &a, &b);
			v[b].push_back(a);
			in[a]++;
			if(a == b && a == 0)
				break;
		}
		int root;
		FOR(i, n)
		{
			if(!in[i])
			{
				root = i;
				break;
			}
		}
		dfs(root);
		printf("%d\n", max(dp[root][0], dp[root][1]));
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值