题目链接
思路:用dp数据来记录价值,开数组用下标记录去或者不去、
则状态转移方程为:
DP[i][1] += DP[j][0],
DP[i][0] += max{DP[j][0],DP[j][1]};其中j为i的孩子节点。
这样,从根节点r进行dfs,最后结果为max{DP[r][0],DP[r][1]}。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=6e3+5;
int father[N],vis[N],dp[N][2],t;
void dfs(int node)
{
int i,j;
vis[node]=1;
for(i=1;i<=t;i++)
if(!vis[i]&&father[i]==node)
{
dfs(i);
dp[node][1]+=dp[i][0];
dp[node][0]+=max(dp[i][0],dp[i][1]);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int i,j,l,k,root;
while(~scanf("%d",&t))
{
for(i=1;i<=t;i++)
scanf("%d",&dp[i][1]);
root=0;
while(scanf("%d%d",&l,&k),l+k>0)
{
father[l]=k;
root=k;
}
memset(vis,0,sizeof(vis));
dfs(root);
printf("%d\n",max(dp[root][1],dp[root][0]));
}
return 0;
}