hdu1520 Anniversary party 树形dp

来源:互联网 发布:二次元轻小说软件 编辑:程序博客网 时间:2024/05/16 09:12

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1520

题意:

大学里有n个员工,除了校长外每个人都有一个直属上级,每个人都有一个欢乐度,现在要求,对于任意一个人,和他的直属上级,只能有一个人到场,求到场的人的最大欢乐度

思路:

树形dp入门。可以发现所有的人的关系是树结构,定义dp[i][0]为以i为根的子树在i不到场时取得的最大欢乐度,dp[i][1]为为以i为根的子树在i到场时取得的最大欢乐度,显然,当i不到场时,i的直属下级j可以到场也可以不到场,所以有dp[i][0]+=max(dp[j][0],dp[j][1]),当i到场时,j不能到场,故有dp[i][1]+=dp[j][0]

#include <bits/stdc++.h>using namespace std;const int N = 10000 + 10, INF = 0x3f3f3f3f;struct edge{    int to, next;}g[N*2];int cnt, head[N];int deg[N];int dp[N][2];void init(){    cnt = 0;    memset(head, -1, sizeof head);    memset(deg, 0, sizeof deg);    memset(dp, 0, sizeof dp);}void add_edge(int v, int u){    g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;}void dfs(int v, int fa){    for(int i = head[v]; ~i; i = g[i].next)    {        int u = g[i].to;        if(u == fa) continue;        dfs(u, v);        dp[v][0] += max(dp[u][0], dp[u][1]);        dp[v][1] += dp[u][0];    }}int main(){    int n;    while(~ scanf("%d", &n))    {        init();        for(int i = 1; i <= n; i++) scanf("%d", &dp[i][1]);        int x, y;        while(scanf("%d%d", &x, &y), x || y)        {            add_edge(y, x);            deg[x]++;        }        int root = 0;        for(int i = 1; i <= n; i++)            if(deg[i] == 0) root = i;        dfs(root, 0);        printf("%d\n", max(dp[root][0], dp[root][1]));    }    return 0;}