Advertisement
erek1e

IOI '05 P6 - Rivers

Jul 6th, 2023
646
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.28 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. const int INF = 2e9 + 1e8;
  8.  
  9. int n, k;
  10. vector<vector<int>> children;
  11. vector<int> w, v, d;
  12.  
  13. // minimum cost of subtree with root, k, with next sawmill being in fixed ancestor
  14. vector<vector<int>> subSubtreeAnswer;
  15.  
  16. // root, k, minimum cost with root being sawmill
  17. vector<vector<int>> subtreeAnswer;
  18.  
  19. void subDfs(int node, int ancestor, int distanceToSawmill) {
  20.     subSubtreeAnswer[node] = {w[node]*distanceToSawmill};
  21.     // consider not selecting this node as a sawmill
  22.     for (int child : children[node]) {
  23.         subDfs(child, ancestor, distanceToSawmill + d[child]);
  24.         int a = subSubtreeAnswer[node].size(), b = subSubtreeAnswer[child].size();
  25.         --a, --b;
  26.         int c = min(a+b, k);
  27.         vector<int> newAns(1+c, INF);
  28.         for (int i = 0; i <= a; ++i) {
  29.             for (int j = 0; j <= b && i+j <= c; ++j) {
  30.                 newAns[i+j] = min(newAns[i+j], subSubtreeAnswer[node][i] + subSubtreeAnswer[child][j]);
  31.             }
  32.         }
  33.         subSubtreeAnswer[node] = newAns;
  34.     }
  35.  
  36.     // consider selecting this node as a sawmill
  37.     if (node != ancestor) {
  38.         while (subSubtreeAnswer[node].size() < subtreeAnswer[node].size()) {
  39.             subSubtreeAnswer[node].push_back(INF);
  40.         }
  41.         for (size_t i = 1; i < subtreeAnswer[node].size(); ++i) {
  42.             subSubtreeAnswer[node][i] = min(subSubtreeAnswer[node][i], subtreeAnswer[node][i]);
  43.         }
  44.     }
  45. }
  46.  
  47. void dfs(int node) {
  48.     for (int child : children[node]) dfs(child);
  49.    
  50.     subDfs(node, node, 0);
  51.  
  52.     subtreeAnswer[node].resize(subSubtreeAnswer[node].size()+1);
  53.     for (size_t i = 1; i < subtreeAnswer[node].size(); ++i) subtreeAnswer[node][i] = subSubtreeAnswer[node][i-1];
  54.     // +1 sawmill because this node itself is chosen
  55. }
  56.  
  57. int main() {
  58.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  59.     cin >> n >> k;
  60.     children.resize(1+n);
  61.     w = v = d = vector<int>(1+n);
  62.     for (int i = 1; i <= n; ++i) {
  63.         cin >> w[i] >> v[i] >> d[i];
  64.         children[v[i]].push_back(i);
  65.     }
  66.     ++k; // include choosing the root
  67.  
  68.     subtreeAnswer.resize(1+n), subSubtreeAnswer.resize(1+n);
  69.     dfs(0);
  70.     cout << subtreeAnswer[0][k] << endl;
  71.     return 0;
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement