简而言之,就是利用了广度优先搜索的思想
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
#define MAX 100010
int head[MAX];
int f[MAX][2];
int cur=0;
//v是u相连的另一点,next为与u相连的另一条边上一条边
struct node{
int v,next;
}edge[MAX*2];
void add(int u,int v){
node E={v,head[u]};
edge[cur]=E;
head[u]=cur++;
}
void bfs(int u,int par){
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if (par==v){ continue; } //不再重复计算他的父节点
bfs(v,u);
f[u][1]+=f[v][0]; //只有一种可能
f[u][0]+=max(f[v][0],f[v][1]); //两种可能中取大的一种
}
}
int main()
{
int n; cin>>n;
memset(f,0,sizeof(f));
memset(head,-1,sizeof(head));
int a,b;
for (int i=1;i<=n;i++)
{
cin>>f[i][1];
}
for (int i=1;i<n;i++)
{
cin>>a>>b;
add(a,b);
add(b,a); //无向边
}
bfs(1,-1);
cout<<max(f[1][0],f[1][1])<<endl;
return 0;
}