有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?
标签:des style blog class code ext
5 1 2 3 4 5 1 2 1 3 2 4 2 5
12
#include <cstdio>
using namespace std;
int val[100001],dp[100001],son[100001],gson[100001],first[100001],next[200002],to[200002],que[100001],far[100001];
bool vis[100001];
int main()
{
int n,i,u,v,ans;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++) first[i]=-1,vis[i]=son[i]=gson[i]=dp[i]=0;
for(i=1;i<=n;i++) scanf("%d",&val[i]);
for(i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);
to[i*2]=v;
next[i*2]=first[u];
first[u]=i*2;
to[i*2+1]=u;
next[i*2+1]=first[v];
first[v]=i*2+1;
}
int top=0,bottom=1;
que[top]=1;
vis[que[top]]=1;
far[1]=-1;
while(top<bottom)//建树
{
for(int e=first[que[top]];e!=-1;e=next[e])
{
if(!vis[to[e]])
{
vis[to[e]]=1;
que[bottom++]=to[e];
far[to[e]]=que[top];//记录父亲节点
}
}
top++;
}
ans=0;
for(i=bottom-1;i>=0;i--)//从树的最下面一层开始往上推
{
dp[que[i]]=val[que[i]]+gson[que[i]]>son[que[i]]?val[que[i]]+gson[que[i]]:son[que[i]];
ans=ans>dp[que[i]]?ans:dp[que[i]];
if(far[que[i]]!=-1)
{
son[far[que[i]]]+=dp[que[i]];//更新父节点的son值
if(far[far[que[i]]]!=-1)
gson[far[far[que[i]]]]+=dp[que[i]];//更新祖父节点的gson值
}
}
printf("%d\n",ans);
}
}
wust-1299-结点选择(树形DP),布布扣,bubuko.com
标签:des style blog class code ext
原文地址:http://blog.csdn.net/faithdmc/article/details/25244693