URAL 1039 / poj2342-Anniversary Party-树形DP

http://poj.org/problem?id=2342 

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17663


题意:

某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。


状态是每个点的取舍。

分别可以用dp[i,1]和dp[i,0]表示第i个人来和不来。


当i来的时候,dp[i][1] += dp[j][0];//j为i的下属

当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属


 

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
typedef unsigned __int64 ull; 
const double pi=acos(-1.0);
double eps=0.000001;
 int max(int a,int b)
 {return a<b?b:a;}
int tm[6005];
int n;
int vis[6005];
vector< vector<int > > mp(6005);
int dp[6005][2];
void dfs(int x)
{
	int i;
	dp[x][1]=tm[x];
	dp[x][0]=0;
	for (i=0;i<mp[x].size();i++)
	{
		int v=mp[x][i];
		dfs(v);
		dp[x][1]+=dp[v][0];
		dp[x][0]+=max(dp[v][1],dp[v][0]);
	}
 
}
int main()
{ 
	cin>>n;
int i;
	for (i=1;i<=n;i++)
		scanf("%d",&tm[i]);
int x,y;
	for (i=1;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		mp[y].push_back(x);
		vis[x]=1;
	}
	scanf("%d %d",&x,&y);
	for (i=1;i<=n;i++)
	{
		if (!vis[i]) break;
	}
	int root=i;
	dfs(root);
 printf("%d\n",max(dp[root][1],dp[root][0]));
 
	return 0;
	
}

你可能感兴趣的:(URAL 1039 / poj2342-Anniversary Party-树形DP)