分析:
树形 d p dp dp简单题
f
i
f_i
fi表示以
i
i
i为根节点的最大子树和
f
i
f_i
fi的初值就是
a
i
a_i
ai了
显然 如果
i
i
i的子节点权值
>
0
>0
>0
i
i
i就可以保留这个子节点了
那么
f
i
=
a
i
+
m
a
x
{
f
s
o
n
,
0
}
f_i=a_i+max\{f_{son},0\}
fi=ai+max{fson,0}
最后
f
i
f_i
fi取
m
a
x
max
max就好了 注意有负数 所以赋初值要赋小
CODE:
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=16005;
int n,head[N],tot,f[N];
struct node{
int to,next;
}a[N<<1];
void add(int x,int y)
{
a[++tot]=(node){y,head[x]};
head[x]=tot;
}
void dfs(int x,int fa)
{
for(int i=head[x];i;i=a[i].next)
{
int qwq=a[i].to;
if(qwq==fa) continue;
dfs(qwq,x);
if(f[qwq]>0) f[x]+=f[qwq];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
f[i]=x;
}
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1,0);
int ans=-0x7fffffff;
for(int i=1;i<=n;i++)
ans=max(ans,f[i]);
printf("%d",ans);
return 0;
}