题解 P1122 【最大子树和】
直接dp,建棵树,dp[i]表示取以i为根的子树最大的收益是多少,因为要联通,所以更新是dp[i]=max(dp[i],dp[i]+dp[j]),j是i的儿子,最后循环一遍n,看dp值最大是多少就可以了。
[codec ]#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int M=32100;
int n,s;
int to[M],w[M],first[M],next[M],dp[M];
void add(int x,int y){
to[++s]=y; next[s]=first[x]; first[x]=s;
}
void dfs(int x,int fa){
dp[x]=w[x];
for(int i=first[x];i>0;i=next[i]){
int y=to[i];
if(y==fa) continue;
dfs(y,x);
if(dp[y]>0) dp[x]+=dp[y];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
}
for(int i=1;i<=n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1,0);
int ans=-16000010;
for(int i=1;i<=n;i++) if(dp[i]>ans) ans=dp[i];
printf("%d",ans);
} [/codec ]