输入:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出:
5
备注:
1 ≤ N ≤ 6000
-128 ≤ Hi ≤ 127
思路: 核心:树形dp
最大独立子集
确定状态转移方程
每个结点分选和不选的情况
假设x为结点
情况一 x选,儿子都不选
f[x][1]=∑f[son][o]
情况二 x不选,儿子选和不选都行,选大的
f[x][0]=∑max( f[son][0],f[son][1] )
//dp
//f[x][1]选=和f[son]][0]
//f[x][0]不选=和max( f[son][0],f[son][1] )
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int ans=0;
const int N=6000+10;
int tot=0;
int happy[N];
int head[N];
int f[N][2];
struct node
{
int t,next;
}edge[N];
void addedge(int x,int y)
{
edge[++tot].t=y;
edge[tot].next=head[x];
head[x]=tot;
}
void dfs(int x,int fa)
{
for(int i=head[x] ;i!=-1 ;i=edge[i].next)
{
int y=edge[i].t;
if( y==fa ) continue;
dfs(y,x);
f[x][1]+=f[y][0];
f[x][0]+=max(f[y][1], f[y][0]);
}
ans=max(ans,f[x][1]);
ans=max(ans,f[x][0]);
}
int main()
{
int n;
cin>>n;
for(int i=1 ;i<=n ;i++)
{cin>>f[i][1];head[i]=-1;}
while(1)
{
int x,y;
cin>>x>>y;
if( x==0 && y==0 ) break;
addedge(x,y);
addedge(y,x);
}
dfs(1,0);
cout<<ans<<endl;
}