Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <tuple>
- #include <set>
- using namespace std;
- class DSU {
- public:
- vector<int> parent;
- vector<int> height;
- DSU(int n) {
- parent.resize(n);
- for (int i = 0; i < n; ++i) {
- parent[i] = i;
- }
- height.assign(n, 0);
- }
- int findRoot(int v) {
- if (v == parent[v]) {
- return v;
- }
- int ans = findRoot(parent[v]);
- parent[v] = ans;
- return ans;
- }
- void Union(int v1, int v2) {
- if (height[v1] >= height[v2]) {
- parent[v2] = v1;
- height[v1] = max(height[v1], height[v2] + 1);
- } else {
- parent[v1] = v2;
- height[v2] = max(height[v2], height[v1] + 1);
- }
- }
- };
- int main() {
- int n, m;
- cin >> n >> m;
- DSU graph(n);
- vector<pair<pair<int, int>, pair<int, int>>> edges;
- vector<int> edge_weight;
- for (size_t i = 0; i < m; ++i) {
- int v1, v2, w;
- cin >> v1 >> v2 >> w, --v1, --v2;
- edges.emplace_back(make_pair(w, i), make_pair(v1, v2));
- edge_weight.emplace_back(w);
- }
- int p5, q5, p6, q6;
- cin >> p5 >> q5 >> p6 >> q6;
- sort(edges.begin(), edges.end());
- int edge_cnt = 0;
- vector<int> used_edges;
- vector<int> pack(q5 + 1, -1);
- int max_possible = 0;
- //weight.first - weight, weight.second - index
- for (auto [weight, coord]: edges) {
- if (graph.findRoot(coord.first) != graph.findRoot(coord.second)) {
- graph.Union(graph.findRoot(coord.first), graph.findRoot(coord.second));
- ++edge_cnt;
- used_edges.emplace_back(weight.second);
- for (int i = q5; i > 0; --i) {
- if (pack[i] > -1 && i + weight.first <= q5) {
- pack[i + weight.first] = weight.second;
- max_possible = max(i + weight.first, max_possible);
- } else if (pack[i] == -1) {
- pack[i] = weight.second;
- max_possible = max(i, max_possible);
- }
- }
- }
- }
- if (edge_cnt < n - 1) {
- cout << "impossible";
- } else {
- set<int> cheap;
- while (max_possible > 0) {
- cheap.emplace(pack[max_possible]);
- max_possible -= edge_weight[pack[max_possible]];
- }
- int total_cost = 0;
- for (auto edge: used_edges) {
- if (!cheap.contains(edge)) {
- q6 -= edge_weight[edge];
- total_cost += edge_weight[edge] * p6;
- } else {
- total_cost += edge_weight[edge] * p5;
- }
- }
- if (q6 < 0){
- cout << "impossible";
- } else {
- cout << total_cost << '\n';
- for (auto edge: used_edges){
- if (cheap.contains(edge)){
- cout << edge + 1 << " 5\n";
- } else {
- cout << edge + 1 << " 6\n";
- }
- }
- }
- }
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement