题目传送门
记忆化搜索,以每个不为负数的花为根,向外扩展,找最大联通块.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
int n,a[16001],tot,head[16001],oo[16001],aa;
struct mm {
map<int,int> f;
}ff[16001];
struct kkk {
int to,next;
}e[160000];
inline void add(int x,int y) {
e[++tot].to = y;
e[tot].next = head[x];
head[x] = tot;
oo[y]++;
}
inline int dp(int rt,int fa,int id) {
int ans = a[rt],d = -1;
if(ff[fa].f[rt] != 0) return ff[fa].f[rt];
for(int i = head[rt];i; i = e[i].next) {
int u = e[i].to;
d++;
if(u == fa) continue;
int sum = dp(u,rt,d);
if(sum > 0) ans += sum;
}
ff[fa].f[rt] = ans;
return ans;
}
int main() {
scanf("%d",&n);
for(int i = 1;i <= n; i++)
scanf("%d",&a[i]);
for(int i = 1;i < n; i++) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i = 1;i <= n; i++) {
if(a[i] < 0) continue;
int o = dp(i,0,0);
aa = max(aa,o);
}
printf("%d",aa);
return 0;
}