POJ2342[Anniversary party] 树上动态规划

来源:互联网 发布:网络扣字大手排行榜 编辑:程序博客网 时间:2024/05/29 18:34

题意:

某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

题目传送门

解题思路:

树形DP, 用dp[i][0/1]来表示i节点选不选,就有状态转移方程

dp[i][1] += dp[j][0]

dp[i][0] += max( dp[j][0], dp[j][1] )

其中,j表示i的儿子节点


贴个代码

#include <cstdio>#include <cstring>#include <iostream>using namespace std;int father[6020], dp[6020][2];bool vis[6020];int n;void Tree_Dp( int node ){     vis[node] = 1;     for ( int i = 1; i <= n; i++ )        if  ( !vis[i] && father[i] == node ){            Tree_Dp(i);            dp[node][1] += dp[i][0];            dp[node][0] += max( dp[i][1], dp[i][0]);        }   }int main(){    while ( scanf( "%d", &n) != EOF ){        memset( father, 0, sizeof(father));        memset( dp, 0, sizeof(dp));        memset( vis, false, sizeof(vis));        int x, y=1, root;        for ( int i = 1; i <= n; i++) scanf( "%d", &dp[i][1]);        for ( ; x||y ;) scanf( "%d%d", &x, &y), father[x] = y;        root = y;        while ( father[root] ){            root = father[root];        }        Tree_Dp( root );        printf( "%d\n", max( dp[root][1], dp[root][0]));    }    return 0;}