HDU 1520 Anniversary party

Problem Description

There is going to be a partyto celebrate the 80-th Anniversary of the Ural State University. The Universityhas a hierarchical structure of employees. It means that the supervisorrelation forms a tree rooted at the rector V. E. Tretyakov. In order to makethe party funny for every one, the rector does not want both an employee andhis or her immediate supervisor to be present. The personnel office hasevaluated conviviality of each employee, so everyone has some number (rating)attached to him or her. Your task is to make a list of guests with the maximalpossible sum of guests' conviviality ratings.

 

 

Input

Employees are numbered from 1to N. A first line of input contains a number N. 1 <= N <= 6 000. Each ofthe subsequent N lines contains the conviviality rating of the correspondingemployee. Conviviality rating is an integer number in a range from -128 to 127.After that go T lines that describe a supervisor relation tree. Each line ofthe tree specification has the form:
L K
It means that the K-th employee is an immediate supervisor of the L-themployee. Input is ended with the line
0 0

 

 

Output

Output should contain themaximal sum of guests' ratings.

 

 

Sample Input

7

1

1

1

1

1

1

1

1 3

2 3

6 4

7 4

4 5

3 5

0 0

 

 

Sample Output

5

题目简介:有一个聚会,每个人参加聚会获得的愉悦值不同。然后呢,有一个条件就是,如果他的直属上司在场,那么他将不愉悦。因此为了获得最大的愉悦值,他和他的直属上司不能同时在场。每个人的愉悦值可正可负。输入n个人,然后下面n排分别表示第i个人的愉悦值。接着是成员之间的关系。虽然是以0 0结束,但是这道题貌似一定形成一棵树,不会形成森林。所以,一定是n-1排的关系。

方法:很显然是一个树形DP的问题。做法很多,我同学是从任意点进入进行DP的方法。不过,个人感觉自己的做法比较容易理解。先建树,然后找到根结点,即是没有入度的点。(用的一个vector反向存储,其实用标记数组标记一下就OK 了,这里当时略SB了)然后就开始DP。是否取这个点,如果取,就是f[i][1],不取就是f[i][0]。那么,取的话,就一定是f[i][1] = f[j][0]+a[i](f[j][0]表示i的子节点不取);如果取那么就是f[i][0]= max(f[j][1],f[j][0]),即是他的每个子节点取或者不取状态的最大值相加。

 

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

int f[6010][2] ,a[6010];
vector<int> v[6010] ,rv[6010];

void deal(int x)
{
	int i;
	if(v[x].size())
	{
		for(i = 0;i<v[x].size();i++)
		{
			deal(v[x][i]);
		}
	}

	f[x][1] += a[x];
	f[x][0] = 0;
	for(i = 0;i<v[x].size();i++)
	{
		f[x][1] += f[v[x][i]][0];

		if(f[v[x][i]][0] > f[v[x][i]][1])
		{
			f[x][0] += f[v[x][i]][0];
		}
		else
		{
			f[x][0] += f[v[x][i]][1];
		}
	}
};

int main()
{
	int n ,i ,b ,c;

	while(scanf("%d",&n)!=EOF)
	{
		for(i = 0;i<6010;i++)
		{
			v[i].clear();
			rv[i].clear();
		}
		for(i = 1;i<=n;i++)
		{
			scanf("%d",&a[i]);
		}
		while(scanf("%d%d",&c,&b)!=EOF)
		{
			if(b==0&&c==0)
			{
				break;
			}
			v[c].push_back(b);
			rv[b].push_back(c);
		}
		int num;
		for(i = 1;i<=n;i++)
		{
			if(rv[i].empty())
			{
				num = i;
				break;
			}
		}

		memset(f,0,sizeof(f));
		deal(num);

		if(f[num][0] > f[num][1])
		{
			printf("%d\n",f[num][0]);
		}
		else
		{
			printf("%d\n",f[num][1]);
		}
	}
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值