http://acm.hdu.edu.cn/showproblem.php?pid=1011
入门级树dp,这题就是要注意一下输入的时候要特判一个m为0的情况。
View Code
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 10 const int maxn = 105; 11 12 int dp[maxn][maxn]; 13 bool vis[maxn]; 14 int p[maxn], b[maxn]; 15 vector<int> nd[maxn]; 16 17 int max2(int x, int y){return (x > y) ? x : y;} 18 19 void init(int n, int m){ 20 for (int i = 1; i <= n; i++){ 21 vis[i] = false; 22 p[i] = b[i] = 0; 23 nd[i].clear(); 24 } 25 memset(dp, 0, sizeof(dp)); 26 } 27 28 bool data(int &n, int &m){ 29 scanf("%d%d", &n, &m); 30 if (n == -1 && m == -1) return false; 31 init(n, m); 32 for (int i = 1; i <= n; i++){ 33 scanf("%d%d", &b[i], &p[i]); 34 } 35 for (int i = 1, x, y; i < n; i++){ 36 scanf("%d%d", &x, &y); 37 nd[x].push_back(y); 38 nd[y].push_back(x); 39 } 40 return true; 41 } 42 43 void dfs(int m, int rt){ 44 vis[rt] = true; 45 int bg = (b[rt] + 19) / 20; 46 47 for (int i = bg; i <= m; i++) 48 dp[rt][i] = p[rt]; 49 if (bg <= m && !nd[rt].size()){ 50 return ; 51 } 52 for (int i = 0; i < nd[rt].size(); i++){ 53 if (vis[nd[rt][i]]) continue; 54 dfs(m, nd[rt][i]); 55 for (int j = m; j >= bg; j--){ 56 for (int k = 1; k <= j - bg; k++){ 57 dp[rt][j] = max2(dp[rt][j - k] + dp[nd[rt][i]][k], dp[rt][j]); 58 } 59 } 60 } 61 } 62 63 int main(){ 64 int n, m; 65 66 while (true){ 67 if (!data(n, m)) return 0; 68 if (!m){ 69 printf("0\n"); 70 continue; 71 } 72 dfs(m, 1); 73 printf("%d\n", dp[1][m]); 74 } 75 }
——written by Lyon