Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <vector>
- #include <algorithm>
- #include <climits>
- void make_set(std::vector<int>& p, std::vector<int>& rank, int n) {
- p.clear();
- for (int i = 0; i < n; ++i) {
- p.push_back(i);
- rank.push_back(1);
- }
- }
- int find_set(int a, std::vector<int>& p) {
- if (a == p[a])
- return a;
- p[a] = find_set(p[a], p);
- return p[a];
- }
- void union_set(int a, int b, std::vector<int>& p,
- std::vector<int>& rank) {
- a = find_set(a, p);
- b = find_set(b, p);
- if (rank[a] > rank[b]) {
- p[b] = a;
- } else {
- if (rank[a] == rank[b]) {
- rank[a] += 1;
- p[b] = a;
- } else {
- p[a] = b;
- }
- }
- }
- struct edge {
- int w;
- int a;
- int b;
- int idx;
- };
- bool edgeComp(const edge& a, const edge& b) {
- return a.w < b.w;
- }
- int main() {
- std::ifstream inp("input.txt");
- int n, m;
- inp >> n >> m;
- std::vector<edge> e;
- int a, b, c;
- edge tmp;
- for (int j = 0; j < m; ++j) {
- inp >> a >> b >> c;
- --a;
- --b;
- tmp.w = c;
- tmp.a = a;
- tmp.b = b;
- tmp.idx = j + 1;
- e.push_back(tmp);
- }
- std::vector<int> p;
- std::vector<int> rank;
- make_set(p, rank, n);
- int e1, e2;
- int w;
- std::sort(e.begin(), e.end(), edgeComp);
- int sum = 0;
- std::vector<int> cabLen;
- std::vector<int> cab2idx;
- for (int i = 0; i < m; ++i) {
- e1 = e[i].a;
- e2 = e[i].b;
- w = e[i].w;
- a = find_set(e1, p);
- b = find_set(e2, p);
- if (a == b)
- continue;
- sum += w;
- cabLen.push_back(w);
- cab2idx.push_back(e[i].idx);
- union_set(a, b, p, rank);
- }
- int cost[2];
- int len[2];
- int cost2idx[2];
- cost2idx[0] = 5;
- cost2idx[1] = 6;
- inp >> cost[0] >> len[0] >> cost[1] >> len[1];
- if (len[0] + len[1] < sum) {
- std::cout << "Impossible";
- return 0;
- }
- int swapped = 0;
- if (cost[0] > cost[1]) {
- int tmp = cost[0];
- cost[0] = cost[1];
- cost[1] = tmp;
- tmp = len[0];
- len[0] = len[1];
- len[1] = tmp;
- tmp = cost2idx[0];
- cost2idx[0] = cost2idx[1];
- cost2idx[1] = tmp;
- swapped = 1;
- }
- std::vector<std::vector<int>> task(cabLen.size() + 1, std::vector<int>(len[0] + 1, 0));
- for (int i = 1; i <= cabLen.size(); ++i) {
- for (int j = 1; j <= len[0]; ++j) {
- task[i][j] = task[i - 1][j];
- if (j < cabLen[i - 1])
- continue;
- for (int k = 0; k < i; ++k)
- if (task[i][j] < (task[k][j - cabLen[i - 1]] + cabLen[i - 1] * cost[0]))
- task[i][j] = task[k][j - cabLen[i - 1]] + cabLen[i - 1] * cost[0];
- }
- }
- int cheapCost = task[cabLen.size()][len[0]];
- std::vector<int> cab2cat(cabLen.size(), cost2idx[1]);
- int i = cabLen.size();
- int j = len[0];
- while (i > 0 && j > 0) {
- if (task[i][j] == task[i - 1][j]) {
- --i;
- continue;
- }
- int k = i - 1;
- while (task[i][j] != (task[k][j - cabLen[i - 1]] + cabLen[i - 1] * cost[0]))
- --k;
- cab2cat[i - 1] = cost2idx[0];
- j = j - cabLen[i - 1];
- i = k;
- }
- int totalCost = 0;
- int totalLen = 0;
- for (i = 0; i < cabLen.size(); ++i)
- if (cab2cat[i] == 5) {
- if (swapped) {
- totalCost += cabLen[i] * cost[1];
- totalLen += cabLen[i];
- }
- else {
- totalCost += cabLen[i] * cost[0];
- }
- } else {
- if (swapped) {
- totalCost += cabLen[i] * cost[0];
- }
- else {
- totalCost += cabLen[i] * cost[1];
- totalLen += cabLen[i];
- }
- }
- if (totalLen > len[1]) {
- std::cout << "Impossible";
- return 0;
- }
- std::cout << totalCost << std::endl;
- for (i = 0; i < cabLen.size(); ++i) {
- std::cout << cab2idx[i] << " " << cab2cat[i] << std::endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement