Guest User

Untitled

a guest
Aug 19th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1. // Задача очень похожа на задачу о максимальном независимом множестве. Тогда она решается следующим
  2. // образом, для данного корня дерева максимальная сумма будет достигаться либо когда мы берем текущий корень
  3. // и его "внуков" или мы не берем текущий корень, а берем "сыновей". Эту задачу решает класс task118_1.
  4. // С другой стороны, в условии не сказано что множество должно быть максимальным по включению и кроме того веса
  5. // узлов могут быть отрицательными. Это навидит на мысль, что узел можно не надо брать если его вес < 0. Это
  6. // решается классе task118_2 (есть одно "но", на выходе может получиться пустое множество). Если это недопустимо
  7. // то случай всех отрицательных весов можно рассмотреть отдельно (task118_3). Короче, мораль следующая - надо или
  8. // более аккуратно формулировать задачу или давать больше примеров:-) Да, дерево считаем n-арным
  9.  
  10. #include <iostream>
  11. #include <vector>
  12. #include <limits>
  13. #include <algorithm>
  14.  
  15. using namespace std;
  16.  
  17.  
  18. class task118
  19. {
  20. protected:
  21. const vector<int>& Values;
  22. vector<int> Results;
  23. const unsigned long N;
  24. vector<vector<int>> Tree;
  25.  
  26. private:
  27.  
  28. vector<vector<int>> build_tree(const vector<pair<int,int>>& edges)
  29. {
  30. vector<vector<int>> result(N, vector<int>());
  31.  
  32. for (const auto& p : edges) {
  33. result[p.first-1].push_back(p.second-1);
  34. result[p.second-1].push_back(p.first-1);
  35. }
  36.  
  37. return result;
  38. }
  39.  
  40. protected:
  41.  
  42. virtual int walk(int node, int parent) = 0;
  43.  
  44. public:
  45.  
  46. task118(const vector<int>& values, const vector<pair<int,int>>& edges)
  47. : Values(values)
  48. , Results(values.size(), numeric_limits<int>::min())
  49. , N(values.size())
  50. {
  51. Tree = build_tree(edges);
  52. }
  53.  
  54. virtual int solve()
  55. {
  56. return walk(0,-1);
  57. }
  58. };
  59.  
  60. class task118_1 : public task118
  61. {
  62. using task118::task118;
  63. protected:
  64. int walk(int node, int parent) override
  65. {
  66.  
  67. if (Results[node] != numeric_limits<int>::min()) {
  68. return Results[node];
  69. }
  70.  
  71. int sons_sum = 0;
  72.  
  73. for (int child_idx = 0; child_idx < Tree[node].size(); ++child_idx) {
  74. auto son = Tree[node][child_idx];
  75. if (son != parent) {
  76. sons_sum += walk(son, node);
  77. }
  78. }
  79.  
  80. int grandsons_sum = 0;
  81.  
  82. for (int child_idx = 0; child_idx < Tree[node].size(); ++child_idx) {
  83. auto son = Tree[node][child_idx];
  84. if (son != parent) {
  85. for (int child_idx = 0; child_idx < Tree[son].size(); ++child_idx) {
  86. auto grand_son = Tree[son][child_idx];
  87. if (grand_son != node) {
  88. grandsons_sum += walk(grand_son, son);
  89. }
  90. }
  91. }
  92. }
  93.  
  94. Results[node] = max(0, max(sons_sum,Values[node] + grandsons_sum));
  95. return Results[node];
  96. }
  97. };
  98.  
  99. class task118_2 : public task118
  100. {
  101. using task118::task118;
  102. protected:
  103. int walk(int node, int parent) override
  104. {
  105.  
  106. if (Results[node] != numeric_limits<int>::min()) {
  107. return Results[node];
  108. }
  109.  
  110. int sons_sum = 0;
  111.  
  112. for (int child_idx = 0; child_idx < Tree[node].size(); ++child_idx) {
  113. auto son = Tree[node][child_idx];
  114. if (son != parent) {
  115. sons_sum += walk(son, node);
  116. }
  117. }
  118.  
  119. int grandsons_sum = 0;
  120.  
  121. for (int child_idx = 0; child_idx < Tree[node].size(); ++child_idx) {
  122. auto son = Tree[node][child_idx];
  123. if (son != parent) {
  124. for (int child_idx = 0; child_idx < Tree[son].size(); ++child_idx) {
  125. auto grand_son = Tree[son][child_idx];
  126. if (grand_son != node) {
  127. grandsons_sum += walk(grand_son, son);
  128. }
  129. }
  130. }
  131. }
  132.  
  133. Results[node] = max(0, max(sons_sum,max(0, Values[node]) + grandsons_sum));
  134. return Results[node];
  135. }
  136. };
  137.  
  138. class task118_3 : public task118_1
  139. {
  140. public:
  141. int solve() override
  142. {
  143. auto neg = std::all_of(Values.begin(), Values.end(), [](int x) { return x < 0;});
  144. if (neg) {
  145. return *std::max_element(Values.begin(), Values.end());
  146. }
  147. return walk(0,-1);
  148. }
  149. };
Add Comment
Please, Sign In to add comment