题意:每个节点有权值,子节点和父节点不能同时选,问最后能选的最大价值是多少
思路:树形DP入门,由于子节点和父节点不能同时选,那么决策其实就一目了然,对于第i个结点,选还是不选。dp[i][0]为不选取第i个结点时候的最大价值,dp[i][1]为选第i结点的最大价值,那么dp[i][0]+=max(dp[j][1],dp[j][0]),不选第i个结点的时候意味着你可能选了j结点,或者j结点也不选,dp[i][1]+=dp[j][0],j选了i就不能选
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 6050
#define LL long long
int cas=1,T;
vector<int> e[maxn];
int f[maxn];
int a[maxn];
int dp[maxn][2];
void dfs(int u)
{
dp[u][1]=a[u];
for (int i = 0;i<e[u].size();i++)
{
int v = e[u][i];
dfs(v);
dp[u][0]+=max(dp[v][1],dp[v][0]);
dp[u][1]+=dp[v][0];
}
}
int main()
{
int n;
while (scanf("%d",&n)!=EOF)
{
for (int i = 1;i<=n;i++)
{
scanf("%d",&a[i]);
e[i].clear();
f[i]=-1;
dp[i][0]=dp[i][1]=0;
}
int x,y;
while (scanf("%d%d",&x,&y)&&x&&y)
{
f[x]=y;
e[y].push_back(x);
}
int temp = 1;
while (f[temp]!=-1)
temp=f[temp];
dfs(temp);
printf("%d\n",max(dp[temp][1],dp[temp][0]));
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}