题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1018
Dynamic Programming. 首先要根据input建立树形结构,然后在用DP来寻找最佳结果。dp[i][j]表示node i的子树上最多保存j个分支的最佳结果。代码如下:
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 int dp[105][105]; //row -> node id, col -> branches preserved. 23 24 struct link { 25 int parent; 26 int child; 27 int weight; 28 }; 29 30 struct tree { 31 int parent; 32 tree *left, *right; 33 int leftw, rightw; 34 }; 35 36 int N, Q; 37 link links[105]; 38 bool visited[105]; 39 40 tree * construct(int pid) 41 { 42 tree *t = new tree; 43 t->parent = pid; 44 int num = 0; 45 bool found = false; 46 FOR(i, 0, N - 1) 47 { 48 if (visited[i] == false && (links[i].parent == pid || links[i].child==pid)) 49 { 50 visited[i] = true; 51 if (num == 0) 52 { 53 t->leftw = links[i].weight; 54 if(links[i].parent==pid) 55 t->left = construct(links[i].child); 56 else 57 t->left = construct(links[i].parent); 58 num++; 59 } 60 else if (num == 1) 61 { 62 t->rightw = links[i].weight; 63 if(links[i].parent==pid) 64 t->right = construct(links[i].child); 65 else 66 t->right = construct(links[i].parent); 67 found = true; 68 break; 69 } 70 } 71 } 72 if (found == false) 73 { 74 t->left = NULL; 75 t->right = NULL; 76 } 77 return t; 78 } 79 80 int calcuTree(tree *t, int R) 81 { 82 if (t == NULL) 83 return 0; 84 85 int id = t->parent; 86 if (dp[id][R] == -1) 87 { 88 int maxLeft = 0; 89 for (int leftR = 0; leftR <= R; leftR++) 90 { 91 int cleft = 0; 92 int rightR = R - leftR; 93 if (leftR > 0) 94 { 95 cleft += t->leftw; 96 cleft += calcuTree(t->left, leftR - 1); 97 } 98 if (rightR > 0) 99 { 100 cleft += t->rightw; 101 cleft += calcuTree(t->right, rightR - 1); 102 } 103 104 if (cleft > maxLeft) 105 maxLeft = cleft; 106 } 107 dp[id][R] = maxLeft; 108 } 109 return dp[id][R]; 110 } 111 112 int main() 113 { 114 while (scanf("%d %d\n", &N, &Q) != EOF) 115 { 116 FOR(i, 0, N - 1) 117 { 118 int p, c, w; 119 scanf("%d %d %d", &links[i].parent, &links[i].child, &links[i].weight); 120 } 121 122 FOR(i, 0, N - 1) 123 visited[i] = false; 124 125 tree *t = new tree; 126 t = construct(1); 127 128 FOR(i, 0, N + 1) 129 { 130 FOR(j, 0, Q + 1) 131 { 132 dp[i][j] = -1; 133 } 134 } 135 136 FOR(i, 0, N + 1) 137 { 138 dp[i][0] = 0; 139 } 140 141 int ans = calcuTree(t, Q); 142 printf("%d\n", ans); 143 } 144 return 0; 145 }