POJ 2342 Anniversary party树形dp

来源:互联网 发布:董秘助手软件下载 编辑:程序博客网 时间:2024/06/10 10:37

题目链接:POJ 2342




题意:在一个公司里,每个成员都有各自的rating,要参加一次年会,规定  有直接上下级关系的任意两人不能同时参加,并且要使参加年会成员的rating值最大;



题解:关于树形dp—树形dp总结


而对于这题,对于么个成员都有去不去两种可能,用dp[i][0]表示他不去的最大rating值,dp[i][1]表示去的最大rating

因此:

dp[x][0] += max(dp[i][0], dp[i][1]);
dp[x][1] += dp[i][0];//i为x的直接下级



代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define debug 0#define M(a, b) memset(a, b, sizeof(a))const int maxn = 6000 + 5;int father[maxn], a[maxn], n, dp[maxn][2], vis[maxn];void Dp(int x) {vis[x] = 1;for (int i = 1; i <= n; i++) {if (vis[i])//这题用vis[]降低遍历,额 其实并没有什么卵用continue;if (father[i] == x) {Dp(i);//递归调用直接下级dp[x][0] += max(dp[i][0], dp[i][1]);dp[x][1] += dp[i][0];}}}int main() {#if debugfreopen("in.txt", "r", stdin);#endif  //debugint x, y, root;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);dp[i][0] = 0;dp[i][1] = a[i];}M(father, 0);M(vis, 0);while (~scanf("%d%d", &x, &y), x + y) {father[x] = y;//用数组模拟树,记录上下级关系root = y;//root 记录当前的上级}while (father[root])root = father[root];//寻找根节点(目测是boss)Dp(root);//递归printf("%d\n", max(dp[root][0], dp[root][1]));return 0;}


1 0