トピックリンク:HDU1520アニバーサリーパーティー
質問:あなたに木を与えてください、各ポイントには価値があります、父と息子は同時に選ぶことができません、選ばれたポイントの最大値を尋ねてください。
分析:ルートを見つけて、DFSツリーDPを下に移動し、子ノードから親ノードを更新します。dp[i] [1]はiを選択することを意味し、dp [i] [0]はiを選択しないことを意味し、次に更新します。親ノードを後方に;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn=6007;
vector<int> g[maxn];
int a[maxn],dp[maxn][2],ind[maxn];
int n,x,y,rt;
void dfs(int x)
{
dp[x][1]=a[x];dp[x][0]=0;
for(auto y:g[x])
{
dfs(y);
dp[x][1]+=dp[y][0];
dp[x][0]+=max(dp[y][1],dp[y][0]);
}
}
void rua()
{
memset(ind,0,sizeof(ind));
for(int i=1;i<=n;i++) scanf("%d",&a[i]),g[i].clear();
while(~scanf("%d%d",&x,&y) && x && y) g[y].pb(x),ind[x]++;
for(int i=1;i<=n;i++) if(!ind[i]) rt=i;
dfs(rt);
printf("%d\n",max(dp[rt][0],dp[rt][1]));
}
int main()
{
while(~scanf("%d",&n)) rua();
return 0;
}