给一棵树每个节点都有一个权值,求一个权值和联通块。
dp[i]记录以i为根的子树最大的权值和是多少,遍历每个分支v的时候,如果dp[v]>0,就加到dp[i]中,否则直接跳过..
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=22000;
vector<int> g[maxn];
int n,m,k;
int a[maxn];
int sum[maxn];
int x,y;
int tot;
int dp[maxn];
void dfs(int u,int fa)
{
int v;
dp[u]=a[u];
for (int j=0; j<g[u].size(); j++)
{
v=g[u][j];
if (v==fa) continue;
dfs(v,u);
if (dp[v]>0) dp[u]+=dp[v];
}
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&n);
memset(dp,0,sizeof dp);
int ans=-(1<<29);
tot=0;
for (int i=1; i<=n; i++)
scanf("%d",&a[i]),g[i].clear(),tot+=a[i],ans=max(ans,a[i]);
for (int i=1; i<n; i++)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,0);
for (int i=1; i<=n; i++)
ans=max(dp[i],ans);
printf("%d\n",ans);
return 0;
}