Advertisement
audreych

14291

Apr 28th, 2024 (edited)
710
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.71 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <sstream>
  4. #include <limits>
  5. // Assume no invalid operation
  6. void FindMaximumPath(std::vector<std::vector<long long int>> &directed_graph, std::vector< long long int> &parent,
  7.                 std::vector<long long int> &value,
  8.                 long long int &max_value, long long int &root_res, long long int current, long long int previous)
  9. {
  10.     // The idea is that for each node, we find 2 paths
  11.     // (the paths from that node to any depth and yields the maximum path)
  12.     // In other words, these 2 paths for each node are the maximum path and the second maximum path.
  13.     // the maximum among all the nodes are the maximum path of the tree
  14.     long long int first_max_path = 0;
  15.     long long int second_max_path = 0;
  16.     for (auto child : directed_graph[current]) {
  17.         FindMaximumPath(directed_graph, parent, value, max_value, root_res, child, current);
  18.  
  19.         if (first_max_path <= value[child]) {
  20.             second_max_path = first_max_path;
  21.             first_max_path = value[child];
  22.         } else {
  23.             if (second_max_path <= value[child]) {
  24.                 second_max_path = value[child];
  25.             }
  26.         }
  27.     }
  28.  
  29.     if (max_value <= first_max_path + second_max_path + value[current]) {
  30.         max_value = first_max_path + second_max_path + value[current];
  31.         root_res = current;
  32.     }
  33.     value[current] += first_max_path; // we need to store the maximum path so far into the nodes that we have visited
  34. }
  35.  
  36. void print_test_graph(std::vector<std::vector<long long int>> &v) {
  37.     int i = 0;
  38.     for (auto x : v) {
  39.         std::cout << i << ' ';
  40.         for (auto y : x) {
  41.             // print pair
  42.             std::cout << y << " ";
  43.         }
  44.         ++i;
  45.         std::cout << '\n';
  46.     }
  47. }
  48. void print_test(std::vector<long long int> &v) {
  49.     int i = 0;
  50.     for (int i = 0; i < v.size(); ++i) {
  51.         std::cout << i << ", " << v[i] << '\n';
  52.     }
  53. }
  54. int main() {
  55.     int n, op;
  56.     // pair of {dest, distance}
  57.     std::cin >> n >> op;
  58.     // no clue why n + op + 1 does not work as size
  59.     std::vector<std::vector<long long int>> directed_graph(20005);
  60.     // this vector stores the value of each node_i and later on, the maximum path at node_i
  61.     std::vector<long long int> value(20005);
  62.     std::vector<long long int> parent(20005);
  63.     std::fill(parent.begin(), parent.end(), -1);
  64.  
  65.     long long int src, dest, d;
  66.     std::cin >> src >> d;
  67.     long long int root = src;
  68.     value[src] = d;
  69.     parent[src] = -1; // we denotes no parents aka root also as -1
  70.     for (int i = 0; i < n; ++i) {
  71.         std::cin >> src >> dest >> d;
  72.         directed_graph[src].push_back(dest);
  73.         value[dest] = d;
  74.         parent[dest] = src;
  75.     }
  76.     std::cin.ignore(); // to ignore newline
  77.     for(int m = 0; m < op; ++m) {
  78.         std::string buf;
  79.         std::getline(std::cin, buf);
  80.         std::istringstream iss(buf);
  81.         std::string s;
  82.  
  83.         std::getline(iss, s, ' ');
  84.         // wonky stuff here Add will break if the directed_graph are suddenly disjointed
  85.         if (s[0] == 'A') {
  86.             std::getline(iss, s, ' ');
  87.             int add_src = std::stoi(s);
  88.             std::getline(iss, s, ' ');
  89.             int add_dest = std::stoi(s);
  90.             std::getline(iss, s, ' ');
  91.             int add_d = std::stoi(s);
  92.             directed_graph[add_src].push_back(add_dest);
  93.             value[add_dest] = add_d;
  94.             parent[add_dest] = add_src;
  95.         } else if (buf[0] == 'C') {
  96.             long long int max_value = std::numeric_limits<long long int>::min();
  97.             long long int root_result = root;
  98.             std::vector<long long int> prev_value = value; // copy the old value so it does not get deleted after runnign the algo
  99.             FindMaximumPath(directed_graph, parent, value, max_value, root_result, root, -1);
  100.             std::cout << "Maximum Value: " << max_value << '\n';
  101.             std::cout << "Root of the Path: " << root_result << '\n';
  102.             value = prev_value;
  103.         } else {
  104.             // Delete
  105.             std::getline(iss, s, ' ');
  106.             long long int node = std::stoi(s);
  107.             long long int par = parent[node];
  108.             if (node > 20005) {
  109.                 continue;
  110.             }
  111.             // This is a bit wonky as we did not delete parent -> child connection
  112.             // but we deleted child -> parent connection
  113.             for (auto child : directed_graph[node]) {
  114.                 directed_graph[par].push_back(child); // transfer children of node to parent
  115.                 parent[child] = par; // set parent of child as par  
  116.             }
  117.             directed_graph[node].clear(); // delete current node's children
  118.             // set parent to -1
  119.             parent[node] = -1;
  120.             // get 9/10 without setting it into negative
  121.             value[node] = std::numeric_limits<long long int>::min(); // actually very important as a placeholder so this won't get count (it might break)
  122.             // THIS IS A WORKAROUND as especially if we delete leaves, we technically do not delete leave,
  123.             // we only set the leaf as 0 weight but DFS can still go
  124.             // First sol : Set a really small number so the path does not every count (more than -100000 (the limit))
  125.             // Second sol : Reiterate the parent node then delete the connection by maybe copying back and forth to the array (more legit solution)
  126.         }
  127.         iss.str("");
  128.     }
  129.     long long int max_value = std::numeric_limits<long long int>::min();
  130.     long long int root_result = root;
  131.     FindMaximumPath(directed_graph, parent, value, max_value, root_result, root, -1);
  132.     std::cout << "Final Root: " << root_result << '\n';
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement