POJ Anniversary party 树形DP

时间:2023-03-08 22:36:21
POJ Anniversary party 树形DP
/*
树形dp:
给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大
对于每一个节点,我们有两种状态
dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能获得的最大权值和
dp[i][1]表示选择节点i ,同上! 转移方程:
dp[i][0]+=max(dp[i_son][1],dp[i_son][0])如果没选择的话,那么子树可选择可不选择
dp[i][1]+=dp[i_son][0] 选择了之后,子树只能不选择
最后输出max(dp[i][0],dp[i][1])即可
*/ #include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define maxn 6002
vector<int> v[maxn];
bool b[maxn];
int dp[maxn][],hp[maxn];
void dfs(int k)
{
int i,len=v[k].size();
dp[k][]= ;
dp[k][]=hp[k];
if(len==)
return ;
for(i=;i<len;i++)
{
dfs(v[k][i]);
dp[k][]+=max(dp[v[k][i]][],dp[v[k][i]][]);
dp[k][]+=dp[v[k][i]][];
}
}
int main()
{
int i,n;
int k,l;
while(cin>>n)
{
for(i=;i<=n;i++)
cin>>hp[i],v[i].clear();
memset(b,,sizeof(b));
while(cin>>l>>k&&k||l)
{
v[k].push_back(l);
b[l]=;
}
for(i=;i<=n;i++)
{
if(!b[i])
break;
}
b[i]=;
dfs(i);
cout<<max(dp[i][],dp[i][])<<endl;
}
return ;
}