题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520
思路:树形DP的入门题
定义dp[root][1]表示以root为根节点的子树,且root本身参加party的最优值,那么dp[root][1]+=Σdp[son][0]+happy[root];
dp[root][0]表示以root为跟节点且root本身没有参加的最优值,那么dp[root][0]+=max(dp[son][0],dp[son][1]);
如果不理解,可以参考我对hdu1054的解释。
代码如下:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define MAX 6010 7 int dp[MAX][2]; 8 int happy[MAX]; 9 class node 10 { 11 public: 12 int to; 13 int next; 14 }; 15 node edge[2*MAX]; 16 int head[MAX]; 17 int vis[MAX]; 18 int n; 19 int tol; 20 void init() 21 { 22 memset(vis,0,sizeof(vis)); 23 memset(head,-1,sizeof(head)); 24 memset(dp,0,sizeof(dp)); 25 tol=0; 26 } 27 void Build_Tree(int u,int v) 28 { 29 edge[tol].to=v; 30 edge[tol].next=head[u]; 31 head[u]=tol++; 32 } 33 void dfs(int root) 34 { 35 vis[root]=1; 36 int hy=happy[root]; 37 for(int i=head[root];i!=-1;i=edge[i].next) 38 { 39 if(vis[edge[i].to]) continue; 40 int son=edge[i].to; 41 dfs(son); 42 43 dp[root][1]+=dp[son][0]; 44 dp[root][0]+=max(dp[son][1],dp[son][0]); 45 } 46 dp[root][1]+=hy; 47 } 48 int main() 49 { 50 while(scanf("%d",&n)!=EOF) 51 { 52 init(); 53 for(int i=1;i<=n;i++) 54 scanf("%d",&happy[i]); 55 int u,v; 56 57 while(scanf("%d%d",&v,&u)!=EOF&&v&&u) 58 { 59 Build_Tree(u,v); 60 Build_Tree(v,u); 61 } 62 dfs(1); 63 cout<<max(dp[1][1],dp[1][0])<<endl; 64 } 65 return 0; 66 }