EOJ 1186 Anniversary party

EOJ 1186 http://acm.cs.ecnu.edu.cn/problem.php?problemid=1186

题意:给定一棵树,选取一定的节点,相邻父子节点不可同时选取。

   树型dp,不能简单地用并查集分组。

   题解:  http://blog.csdn.net/woshi250hua/article/details/7641589

 1 //hdu
 2 
 3 #include <stdio.h>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <string>
 7 #include <algorithm>
 8 #include <iostream>
 9 #include <map>
10 #include <queue>
11 
12 using namespace std;
13 int f[6005];
14 struct E
15 {
16     int v;
17     int next;
18 }e[6005];
19 int head[6005];
20 int ie;
21 int dp[6005][2];
22 int a[6005];
23 
24 void add(int u, int v)
25 {
26     e[ie].v = v;
27     e[ie].next = head[u];
28     head[u] = ie++;
29     //printf("%d -> %d\n", u, v);
30 }
31 
32 void dfs(int t)
33 {
34     //printf("in: %d\n", t);
35     //while(getchar() != '.')
36         //;
37     dp[t][1] = a[t];
38     dp[t][0] = 0;
39     int p = head[t];
40     while(p){
41         dfs(e[p].v);
42         dp[t][1] += dp[e[p].v][0];
43         dp[t][0] += max(dp[e[p].v][0], dp[e[p].v][1]);
44         p = e[p].next;
45     }
46 }
47 
48 int main()
49 {    
50     int n;
51     while(cin >> n)
52     {
53         for(int i=1; i<=n; i++){
54             scanf("%d",  &a[i]);
55             f[i] = i;
56         }
57         int u, v;
58         ie = 1;
59         memset(head, 0, sizeof(head));
60         while(scanf("%d%d", &v, &u), v&&u)
61         {
62             f[v] = u;
63             add(u, v);
64         }
65         int i;
66         for(i=1; i<=n; i++)
67             if(i == f[i])
68             {
69                 dfs(i);
70                 break;
71             }
72         printf("%d\n", max(dp[i][0], dp[i][1]));
73     }
74     
75     return 0;
76 }
View Code

 

    

posted on 2013-07-03 17:19  KimKyeYu  阅读(240)  评论(0编辑  收藏  举报

导航