题意很简单,就是给一个领导班子的关系(肯定不会出现圈)。以及每个人对此次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; }