alwaysBeAStarter

博客园 首页 新随笔 联系 订阅 管理

题目链接: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 }

 

posted on 2017-06-22 18:30  alwaysBeAStarter  阅读(110)  评论(0编辑  收藏  举报