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 }