题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1039
Dynamic Programming. 建立树形结构,每个employee有两个选择,去或者不去。supervisor的选择影响着sub-tree的选择。代码如下:
1 #include <iostream> 2 #include <math.h> 3 #include <stdio.h> 4 #include <cstdio> 5 #include <algorithm> 6 #include <string.h> 7 #include <string> 8 #include <sstream> 9 #include <cstring> 10 #include <queue> 11 #include <vector> 12 #include <functional> 13 #include <cmath> 14 #include <set> 15 #define SCF(a) scanf("%d", &a) 16 #define IN(a) cin>>a 17 #define FOR(i, a, b) for(int i=a;i<b;i++) 18 #define Infinity 9999999 19 typedef long long Int; 20 using namespace std; 21 22 struct tree { 23 int parent; 24 vector<int> children; 25 int size = 0; 26 }; 27 int N; 28 tree * trees[6005]; 29 int dp[6005][2]; //i -> employee id, j -> attend 1 or not 0 30 int conviviality[6005]; 31 32 int calcuTree(int parent, int choice) //choice 1: attend or not, choice 0: cannot atted 33 { 34 if (dp[parent][choice] != Infinity) 35 return dp[parent][choice]; 36 37 int maxCon = 0; 38 int maxConDGo = 0; 39 int maxConGo = conviviality[parent]; 40 //this employee don't go, its child has 2 choices 41 for (int i = 0; i < trees[parent]->size; i++) 42 { 43 int child = trees[parent]->children[i]; 44 if (dp[child][0] == Infinity) 45 dp[child][0] = calcuTree(child, 0); 46 if (dp[child][1] == Infinity) 47 dp[child][1] = calcuTree(child, 1); 48 maxConDGo += max(dp[child][0], dp[child][1]); 49 } 50 51 //this employee go, its child has only one choice. 52 for (int i = 0; i < trees[parent]->size; i++) 53 { 54 int child = trees[parent]->children[i]; 55 if (dp[child][0] == Infinity) 56 dp[child][0] = calcuTree(child, 0); 57 maxConGo += dp[child][0]; 58 } 59 60 if (choice == 1) 61 maxCon = max(maxConGo, maxConDGo); 62 else 63 maxCon = maxConDGo; 64 65 return maxCon; 66 } 67 68 int main() 69 { 70 while (SCF(N) != EOF) 71 { 72 FOR(i, 1, N + 1) 73 SCF(conviviality[i]); 74 int L, K; 75 int index = 0; 76 FOR(i, 1, N + 1) 77 { 78 trees[i] = new tree; 79 trees[i]->parent = i; 80 } 81 82 bool *root = new bool[N + 1]; 83 FOR(i, 0, N + 1) 84 root[i] = true; 85 86 while (scanf("%d %d", &L, &K)) 87 { 88 if (L == 0 && K == 0) 89 break; 90 trees[K]->children.push_back(L); 91 trees[K]->size += 1; 92 root[L] = false; 93 } 94 95 FOR(i, 1, N + 1) 96 { 97 dp[i][0] = dp[i][1] = Infinity; 98 } 99 100 int president = 0; 101 FOR(i, 1, N + 1) 102 { 103 if (root[i]) 104 { 105 president = i; 106 break; 107 } 108 } 109 110 FOR(i, 1, N + 1) 111 { 112 dp[i][0] = calcuTree(i, 0); 113 dp[i][1] = calcuTree(i, 1); 114 } 115 116 int maxAns = max(dp[president][0], dp[president][1]); 117 printf("%d\n", maxAns); 118 } 119 return 0; 120 }