HDU——Anniversary party 树DP入门

来源:互联网 发布:淘宝退款不退货防范 编辑:程序博客网 时间:2024/05/17 02:19

题意很简单,就是给一个领导班子的关系(肯定不会出现圈)。以及每个人对此次party好评度。为了让大家玩的开心,不能同时请一对有直接领导关系的人参加此次活动

,问你如何安排才能使此次参加party人的总的好评度最高dp[i][0]代表不选i人的最优,dp[i][1]代表选i的最优。


这个很简单的状态转移方程:

     dp[i][0]=所有max(dp[i.child][0],dp[i.child][1]);

     dp[i][1]=所有dp[i.child][0];

     叶子节点:dp[i][0]=0,dp[i][1]=好评度,因此任何后推绝对不会出现<0的时候。

     代码如下:

/*  * File:   main.cpp * Author: hit-acm * * Created on 2012年5月21日, 上午11:00 */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include<cmath>using namespace std;const int MAX = 6010;int rate[MAX];int father[MAX];int dp[MAX][2];vector<int> link1[MAX];void init() {    for (int i = 0; i < MAX; i++) {        father[i] = i;    }    memset(dp, 0, sizeof (dp));}int find_ancest(int x) {    if (x == father[x]) return x;    return father[x] = find_ancest(father[x]);}void Union(int x, int y) {    int u, v;    u = find_ancest(x);    v = find_ancest(y);    if (u != v) {        father[v] = u;    }}void DFS(int x) {    int size = link1[x].size();    dp[x][0] = 0;    dp[x][1] = rate[x];    for (int i = 0; i < size; i++) {        int y = link1[x][i];        DFS(y);        dp[x][0] += max(dp[y][0], dp[y][1]);        dp[x][1] += dp[y][0];    }}int main() {    int L, K, N;    while (scanf("%d", &N) != EOF) {        init();        for (int i = 1; i <= N; i++) {            scanf("%d", &rate[i]);            link1[i].clear();        }        while (scanf("%d%d", &L, &K) && (L + K)) {            link1[K].push_back(L);            Union(K, L);        }        int root = find_ancest(1);        DFS(root);        printf("%d\n", max(dp[root][0], dp[root][1]));    }    return 0;}

原创粉丝点击