当前位置: 代码迷 >> 综合 >> POJ2342[Anniversary party] 树上动态规划
  详细解决方案

POJ2342[Anniversary party] 树上动态规划

热度:52   发布时间:2023-11-06 10:08:00.0

题意:

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

题目传送门

解题思路:

树形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;
}