题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520
题目大意:有n个人去参加party,n个人的关系图满足树。每个人都有快乐值,后边跟许多行a b(0,0结束),表示b是a的上司,不能使他和他的上司同时参加,选任意个人的快乐值累加,求可以获得最大的快乐值。
题目思路:普通DP放树上从叶子节点开始跑一遍跑到根节点即可。
在简单点的题目就是N个人排成一排,每个人都有一个快乐值,选任意个人,求任意个人的快乐值相加的最大值。选人条件为选了的人的相邻两个人不能被选。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int dp[2][6005],num[6005],vis[6005];
vector <int> vt[6005];
int n,a,b,root;
void init()
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) vt[i].clear();
}
void read()
{
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
dp[1][i]=num[i];
}
while(cin>>a>>b,a||b)
{
vt[b].push_back(a);
vis[a]=1;
}
}
int findroot()
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0) return i;
}
}
void dfs(int x)
{
for(int i=0;i<vt[x].size();i++) dfs(vt[x][i]);
for(int i=0;i<vt[x].size();i++)
{
int son=vt[x][i];
dp[0][x]+=max(dp[0][son],dp[1][son]);
dp[1][x]+=dp[0][son];
}
return ;
}
void print()
{
printf("%d\n",max(dp[0][root],dp[1][root]));
}
int main()
{
while(cin>>n)
{
init();
read();
root=findroot();
dfs(root);
print();
}
return 0;
}