您的位置:首页 > 其它

POJ 2342 Anniversary party(树形DP入门)

2015-08-26 15:45 375 查看
Anniversary party
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 5343Accepted: 3054
DescriptionThere is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure of employees. It means that the supervisor relation forms a tree rooted at the rector V. E. Tretyakov. In order to make the party funny for every one, the rector does not want both an employee and his or her immediate supervisor to be present. The personnel office has evaluated conviviality of each employee, so everyone has some number (rating) attached to him or her. Your task is to make a list of guests with the maximal possible sum of guests' conviviality ratings.InputEmployees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from -128 to 127. After that go N – 1 lines that describe a supervisor relation tree. Each line of the tree specification has the form: L K It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line 0 0 OutputOutput should contain the maximal sum of guests' ratings.Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
Sample Output
5
    题意:一个公司举行一个酒会,有n个人在被邀请之列,然后每个人都有一个气氛值,但是每个人都不想在酒会上见到自己的直接领导,所以这就导致如果直系领导来那么本人就不回来,要求在这样的情况下就会的最大气氛值为多少。
    思路:首先将每个人的直系领导给记录下来,fathsr[x] = y 代表x的直系领导是y,这样可以有一个关系链。最后会有一个boss没有领导,找到这个人。
    1.设立一个dp[maxn][2]数组,然后分析状态转移方程,每个人有两种状态去与不去,我们将dp[x][0]设为x这个人不去的情况,dp[x][1]设为x这个人去的情况.
    2.那么: dp[y][1] += dp[x][0];
            dp[y][0] += max(dp[x][1],dp[x][0]);
            y是x的直系领导
    3.有了状态转移方程就可以直接写了,DFS到每个叶子节点然后开始计算,假设根节点为root,那么最后的值ans = max(dp[root][1],dp[root][0]);
点击打开链接
#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 6001using namespace std;int dp[2];int father;int v;int n,m;void tree_dp(int xx){    v[xx] = 1;    for(int i=1;i<=n;i++){        if(v[i] == 0 && father[i] == xx){            tree_dp(i);            dp[xx][1] += dp[i][0];            dp[xx][0] += max(dp[i][1],dp[i][0]);        }    }}int main(){    while(scanf("%d",&n)!=EOF){        memset(dp,0,sizeof(dp));        memset(v,0,sizeof(v));        memset(father,0,sizeof(father));        for(int i=1;i<=n;i++){            scanf("%d",&dp[i][1]);        }        int x,y;        while(scanf("%d%d",&x,&y)!=EOF){            if(x == 0 && y == 0){                break;            }            father[x] = y;        }        int root = 1;        while(father[root]){            root = father[root];        }        tree_dp(root);        int ans = max(dp[root][0],dp[root][1]);        printf("%d\n",ans);    }    return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: