洛谷 P1122 最大子树和

题目传送门

记忆化搜索,以每个不为负数的花为根,向外扩展,找最大联通块.

#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;
}
posted @ 2020-09-13 22:48  Mr^Simon  阅读(145)  评论(0编辑  收藏  举报