Advertisement
pasholnahuy

Untitled

Apr 29th, 2023
825
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.66 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <tuple>
  6. #include <set>
  7.  
  8. using namespace std;
  9.  
  10. class DSU {
  11. public:
  12.     vector<int> parent;
  13.     vector<int> height;
  14.  
  15.     DSU(int n) {
  16.         parent.resize(n);
  17.         for (int i = 0; i < n; ++i) {
  18.             parent[i] = i;
  19.         }
  20.         height.assign(n, 0);
  21.     }
  22.  
  23.     int findRoot(int v) {
  24.         if (v == parent[v]) {
  25.             return v;
  26.         }
  27.         int ans = findRoot(parent[v]);
  28.         parent[v] = ans;
  29.         return ans;
  30.     }
  31.  
  32.     void Union(int v1, int v2) {
  33.         if (height[v1] >= height[v2]) {
  34.             parent[v2] = v1;
  35.             height[v1] = max(height[v1], height[v2] + 1);
  36.         } else {
  37.             parent[v1] = v2;
  38.             height[v2] = max(height[v2], height[v1] + 1);
  39.         }
  40.     }
  41.  
  42.  
  43. };
  44.  
  45. int main() {
  46.     int n, m;
  47.     cin >> n >> m;
  48.     DSU graph(n);
  49.     vector<pair<pair<int, int>, pair<int, int>>> edges;
  50.     vector<int> edge_weight;
  51.     for (size_t i = 0; i < m; ++i) {
  52.         int v1, v2, w;
  53.         cin >> v1 >> v2 >> w, --v1, --v2;
  54.         edges.emplace_back(make_pair(w, i), make_pair(v1, v2));
  55.         edge_weight.emplace_back(w);
  56.     }
  57.     int p5, q5, p6, q6;
  58.     cin >> p5 >> q5 >> p6 >> q6;
  59.     int first_cost = p5;
  60.     int first_cnt = q5;
  61.     int second_cost = p6;
  62.     int second_cnt = q6;
  63.     if (p5 > p6){
  64.         swap(first_cnt, second_cnt);
  65.         swap(first_cost, second_cost);
  66.     }
  67.     sort(edges.begin(), edges.end());
  68.     int edge_cnt = 0;
  69.     vector<int> used_edges;
  70.     vector<int> pack(first_cnt + 1, -1);
  71.     int max_possible = 0;
  72.     //weight.first - weight, weight.second - index
  73.     for (auto [weight, coord]: edges) {
  74.         if (graph.findRoot(coord.first) != graph.findRoot(coord.second)) {
  75.             graph.Union(graph.findRoot(coord.first), graph.findRoot(coord.second));
  76.             ++edge_cnt;
  77.             used_edges.emplace_back(weight.second);
  78.             for (int i = first_cnt; i > 0; --i) {
  79.                 if (pack[i] > -1 && i + weight.first <= first_cnt) {
  80.                     pack[i + weight.first] = weight.second;
  81.                     max_possible = max(i + weight.first, max_possible);
  82.                 } else if (pack[i] == -1) {
  83.                     pack[i] = weight.second;
  84.                     max_possible = max(i, max_possible);
  85.                 }
  86.             }
  87.         }
  88.     }
  89.     if (edge_cnt < n - 1) {
  90.         cout << "impossible";
  91.     } else {
  92.         set<int> cheap;
  93.         while (max_possible > 0) {
  94.             cheap.emplace(pack[max_possible]);
  95.             max_possible -= edge_weight[pack[max_possible]];
  96.         }
  97.         int total_cost = 0;
  98.         for (auto edge: used_edges) {
  99.             if (!cheap.contains(edge)) {
  100.                 second_cnt -= edge_weight[edge];
  101.                 total_cost += edge_weight[edge] * second_cost;
  102.             } else {
  103.                 total_cost += edge_weight[edge] * first_cost;
  104.             }
  105.         }
  106.         if (second_cnt < 0){
  107.             cout << "impossible";
  108.         } else {
  109.             cout << total_cost << '\n';
  110.             for (auto edge: used_edges){
  111.                 if (cheap.contains(edge)){
  112.                     if (q5 == first_cnt){
  113.                         cout << edge + 1 << " 5\n";
  114.                     } else {
  115.                         cout << edge + 1 << " 6\n";
  116.                     }
  117.                 } else {
  118.                     if (q5 == first_cnt){
  119.                         cout << edge + 1 << " 6\n";
  120.                     } else {
  121.                         cout << edge + 1 << " 5\n";
  122.                     }
  123.                 }
  124.             }
  125.         }
  126.     }
  127.  
  128.     return 0;
  129. };
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement