简单树形dp
f[x][1]+=f[y][0];
f[x][0]+=max(f[y][0],f[y][1]);
最后加上自己的权值即可。
Code:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct node
{
int x,y,next;
}a[1110000]; int first[110000],len;
int dp[110000][2];
int val[110000],n,m,x,y;
void ins(int x,int y)
{
len++; a[len].x=x; a[len].y=y;
a[len].next=first[x]; first[x]=len;
}
void Input()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
len=0; memset(first,0,sizeof(first));
while(scanf("%d%d",&x,&y)!=EOF)
{
if(x==0&&y==0) break;
else{ins(x,y);ins(y,x);}
}
}
bool vis[110000];
void Treedp(int x)
{
if(vis[x]) return ;
vis[x]=1;
for(int k=first[x];k;k=a[k].next)
{
int y=a[k].y;
if(!vis[y])
{
Treedp(y);
dp[x][1]+=dp[y][0];
dp[x][0]+=max(dp[y][0],dp[y][1]);
}
}
dp[x][1]+=val[x];
}
void Solve()
{
Treedp(1);
}
void Output()
{
printf("%d\n",max(dp[1][1],dp[1][0]));
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
len=0; memset(first,0,sizeof(first));
memset(dp,0,sizeof(dp));
while(scanf("%d%d",&x,&y)!=EOF)
{
if(x==0&&y==0) break;
else{ins(x,y);ins(y,x);}
}
memset(vis,0,sizeof(vis));
Solve();
Output();
}
return 0;
}