hdu 1520
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1520
题意:举办一个party,候选人当中有很多人之间有上下级关系,求没有直接上下级的最多的人数。
mark:简单的树形dp题,从每个人的状态着手考虑,每个人要么参加,要么不参加,那么状态dp[i][0]代表参加,dp[i][1]代表不参加。
dp[i][0] += dp[son][1];
dp[i][1] += max(dp[son][1], dp[son][0]);
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> const int N = 6010; struct node { int v; node *next; }*head[N],tree[2*N]; int n,m,ptr; int w[N],vst[N]; int dp[N][2]; int max(int a, int b) {return a > b ? a : b;} void init() { ptr = 1; memset(vst, 0, sizeof(vst)); memset(dp, 0, sizeof(dp)); memset(head, 0, sizeof(head)); } void AddEdge(int x,int y) { tree[ptr].v = y; tree[ptr].next = head[x],head[x] = &tree[ptr++]; } void dfs(int v) //v代表父亲节点 { vst[v] = 1; node *p = head[v]; dp[v][0] = w[v]; while (p != NULL) { if(vst[p->v]) {p = p->next; continue;} dfs(p->v); //p->v代表v的儿子节点 dp[v][0] += dp[p->v][1]; dp[v][1] += max(dp[p->v][0], dp[p->v][1]); p = p->next; } } int main() { int i,j,k; while(~scanf("%d", &n)) { init(); for(i = 1; i <= n; i++) scanf("%d", w+i); while(scanf("%d%d", &j, &k), j+k) { AddEdge(j, k); AddEdge(k, j); } dfs(1); printf("%d\n", max(dp[1][0], dp[1][1])); } }