标签:
http://acm.hdu.edu.cn/showproblem.php?pid=1520
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
5
/** hdu 1520 树形dp 题目大意:给定一个树形关系网,每一个员工不可以和他的直接上司同时出席聚会,并且每一个人有一个欢乐值, 问邀请那些人参加在不违反规矩的前提下总欢乐值最高。 解题思路:树形dp。dp[u][0]:u不参加,以u为根节点的子树的欢乐值最高值, dp[u][0]:u参加,以u为根节点的子树的欢乐值最高值。 状态转移方程: dp[u][0]+=max(dp[v][1],dp[v][0]); dp[u][1]+=dp[v][0]; 上司参加则下属一定不参加,上司不参加下属参不参加都可以。 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=6005; struct note { int v,next; }edge[maxn*4]; int head[maxn],ip; int n,a[maxn],dp[maxn][2]; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void init() { memset(head,-1,sizeof(head)); ip=0; } void dfs(int u,int pre) { dp[u][0]=0; dp[u][1]=a[u]; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==pre)continue; dfs(v,u); dp[u][0]+=max(dp[v][1],dp[v][0]); dp[u][1]+=dp[v][0]; } } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } init(); for(int i=0;i<n;i++) { int u,v; scanf("%d%d",&u,&v); if(u==0&&v==0)continue; addedge(u,v); addedge(v,u); } memset(dp,0,sizeof(dp)); dfs(1,-1); printf("%d\n",max(dp[1][0],dp[1][1])); } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/43635087