andre_joy

导航

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]));
    }
}

posted on 2012-10-11 08:04  andre_joy  阅读(350)  评论(0编辑  收藏  举报