树形dp基础题
f
[
x
]
[
0
]
f[x][0]
f[x][0]:考虑以
x
x
x为根节点的子树时,不选
x
x
x的最大权值
f
[
x
]
[
1
]
f[x][1]
f[x][1]:考虑以
x
x
x为根节点的子树时,选
x
x
x的最大权值
#include<bits/stdc++.h>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn = 1e6+5;
using namespace std;
int n, cnt;
int head[maxn];
ll w[maxn];
ll f[maxn][2];
struct Edge
{
int to;
int w;
int next;
}edge[maxn*2];
void add(int from, int to)
{
edge[++cnt].to=to;
edge[cnt].next=head[from];
head[from]=cnt;
}
void dfs(int x, int fa)
{
f[x][1]=w[x];
for (int i=head[x]; i; i=edge[i].next){
int son = edge[i].to;
if (fa==son) continue;
dfs(son, x);
ll mf = max(f[son][0], f[son][1]);
f[x][0]=max(f[x][0], mf);
if (f[son][1]>0) f[x][1]+=f[son][1];
}
}
int main()
{
// freopen("1.in","r",stdin);
// freopen("1.txt","w",stdout);
scanf("%d",&n);
for (int i=1; i<=n; i++){
scanf("%lld",&w[i]);
}
for (int i=1; i<=n-1; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
ll ans=f[1][1];
for (int i=2; i<=n; i++){
ans=max(ans,f[i][1]);
}
printf("%lld\n",ans);
// for (int i=1; i<=n; i++){
// printf("%d %d\n",f[i][0],f[i][1]);
// }
return 0;
}