题目:
https://www.luogu.org/problem/show?pid=1352;
套路DP;
由于点权可能为负;
那么上司不来时,下属可来,可不来;
但上司来时,下属一定不能来;
dp[x][0]+=max(dp[v][0],dp[v][1]);
dp[x][1]+=dp[v][0];
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=20001;
int dp[MAXN][4],fst[MAXN],nxt[MAXN],num[MAXN];
int tot,n,fa[MAXN],ans;
struct hh
{
int from,to;
}ma[MAXN];
void build(int f,int t)
{
tot++;
ma[tot]=(hh){f,t};
nxt[tot]=fst[f];
fst[f]=tot;
return;
}
void dfs(int x)
{
for(int i=fst[x];i;i=nxt[i])
{
int v=ma[i].to;
if(fa[x]==v) continue;
dfs(v);
dp[x][0]+=max(dp[v][0],dp[v][1]);
dp[x][1]+=dp[v][0];
}
return;
}
void solve()
{
int x,y;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&num[i]),dp[i][1]=num[i];
while( ~scanf("%d%d",&x,&y))
{
if(x==0 && y==0) break;
fa[x]=y;
build(x,y);
build(y,x);
}
for(int i=1;i<=n;i++)
if(fa[i]==0) {dfs(i);}
for(int i=1;i<=n;i++) ans=max(ans,max(dp[i][0],dp[i][1]));
cout<<ans;
}
int main()
{
solve();
return 0;
}