// Zadanie Alchemik Bajtazar // Rozwiazanie by Jakub Stepaniuk #include <iostream> #include <vector> #include <unordered_set> #include <queue> #include <algorithm> using namespace std; void findAllDists(vector<pair<int, int>>& dist, int start, vector<unordered_set<int>>& G) { dist[start] = {0, start}; queue<int> Q; Q.push(start); int curr; while (!Q.empty()) { curr = Q.front(); Q.pop(); for (auto& x : G[curr]) { if (dist[x].first == -1) { dist[x].first = dist[curr].first + 1; dist[x].second = x; Q.push(x); } } } return; } int main() { int wierzcholki, polaczenia; cin >> wierzcholki; vector<unordered_set<int>> G1(wierzcholki); vector<unordered_set<int>> G2(wierzcholki); cin >> polaczenia; int a, b; for (int i = 0; i < polaczenia; i++) { cin >> a >> b; G1[a - 1].insert(b - 1); G1[b - 1].insert(a - 1); } cin >> polaczenia; for (int i = 0; i < polaczenia; i++) { cin >> a >> b; G2[a - 1].insert(b - 1); G2[b - 1].insert(a - 1); } vector<pair<bool, pair<int, int>>> akcje; // Dodaj stelaz: Polaczenie miedzy wszystkimi wierzcholkami a 0 w kolejnosci od najblizszych do najdalszych. vector<pair<int, int>> dist(wierzcholki, {-1, 0}); findAllDists(dist, 0, G1); sort(dist.begin(), dist.end()); for (int i = 1; i < wierzcholki; i++) { if (dist[i].first > 1) { akcje.push_back({ true, {0, dist[i].second} }); G1[0].insert(dist[i].second); G1[dist[i].second].insert(0); } } // Dodaj wszystkie wierzcholki, ktore sa w G2, a nie ma w G1. for (int i = 0; i < wierzcholki; i++) { for (auto& x : G2[i]) { if (G1[i].count(x) == 0) { akcje.push_back({ true, {i, x} }); G1[i].insert(x); G1[x].insert(i); } } } // Zaczynajac w kolejnosci od najdalszych do najblizszych w G2 usun z G1 wszystkie polaczenia, ktorych nie ma w G2. Polaczenie z 0 usun najpozniej. dist = vector<pair<int, int>>(wierzcholki, { -1, 0 }); findAllDists(dist, 0, G2); sort(dist.begin(), dist.end(), greater<pair<int, int>>()); for (int i = 0; i < wierzcholki; i++) { vector<int> toErase; for (auto& x : G1[dist[i].second]) { if (G2[dist[i].second].count(x) == 0) { toErase.push_back(x); } } sort(toErase.begin(), toErase.end()); for (int j = toErase.size() - 1; j >= 0; j--) { akcje.push_back({ false, {dist[i].second, toErase[j]}}); G1[dist[i].second].erase(toErase[j]); G1[toErase[j]].erase(dist[i].second); } toErase.clear(); } // Wypisz wyniki z akcji: cout << akcje.size() << endl; for (int i = 0; i < akcje.size(); i++) { if (akcje[i].first) { cout << "+ " << akcje[i].second.first + 1 << ' ' << akcje[i].second.second + 1 << endl; } else { cout << "- " << akcje[i].second.first + 1 << ' ' << akcje[i].second.second + 1 << endl; } } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | // Zadanie Alchemik Bajtazar // Rozwiazanie by Jakub Stepaniuk #include <iostream> #include <vector> #include <unordered_set> #include <queue> #include <algorithm> using namespace std; void findAllDists(vector<pair<int, int>>& dist, int start, vector<unordered_set<int>>& G) { dist[start] = {0, start}; queue<int> Q; Q.push(start); int curr; while (!Q.empty()) { curr = Q.front(); Q.pop(); for (auto& x : G[curr]) { if (dist[x].first == -1) { dist[x].first = dist[curr].first + 1; dist[x].second = x; Q.push(x); } } } return; } int main() { int wierzcholki, polaczenia; cin >> wierzcholki; vector<unordered_set<int>> G1(wierzcholki); vector<unordered_set<int>> G2(wierzcholki); cin >> polaczenia; int a, b; for (int i = 0; i < polaczenia; i++) { cin >> a >> b; G1[a - 1].insert(b - 1); G1[b - 1].insert(a - 1); } cin >> polaczenia; for (int i = 0; i < polaczenia; i++) { cin >> a >> b; G2[a - 1].insert(b - 1); G2[b - 1].insert(a - 1); } vector<pair<bool, pair<int, int>>> akcje; // Dodaj stelaz: Polaczenie miedzy wszystkimi wierzcholkami a 0 w kolejnosci od najblizszych do najdalszych. vector<pair<int, int>> dist(wierzcholki, {-1, 0}); findAllDists(dist, 0, G1); sort(dist.begin(), dist.end()); for (int i = 1; i < wierzcholki; i++) { if (dist[i].first > 1) { akcje.push_back({ true, {0, dist[i].second} }); G1[0].insert(dist[i].second); G1[dist[i].second].insert(0); } } // Dodaj wszystkie wierzcholki, ktore sa w G2, a nie ma w G1. for (int i = 0; i < wierzcholki; i++) { for (auto& x : G2[i]) { if (G1[i].count(x) == 0) { akcje.push_back({ true, {i, x} }); G1[i].insert(x); G1[x].insert(i); } } } // Zaczynajac w kolejnosci od najdalszych do najblizszych w G2 usun z G1 wszystkie polaczenia, ktorych nie ma w G2. Polaczenie z 0 usun najpozniej. dist = vector<pair<int, int>>(wierzcholki, { -1, 0 }); findAllDists(dist, 0, G2); sort(dist.begin(), dist.end(), greater<pair<int, int>>()); for (int i = 0; i < wierzcholki; i++) { vector<int> toErase; for (auto& x : G1[dist[i].second]) { if (G2[dist[i].second].count(x) == 0) { toErase.push_back(x); } } sort(toErase.begin(), toErase.end()); for (int j = toErase.size() - 1; j >= 0; j--) { akcje.push_back({ false, {dist[i].second, toErase[j]}}); G1[dist[i].second].erase(toErase[j]); G1[toErase[j]].erase(dist[i].second); } toErase.clear(); } // Wypisz wyniki z akcji: cout << akcje.size() << endl; for (int i = 0; i < akcje.size(); i++) { if (akcje[i].first) { cout << "+ " << akcje[i].second.first + 1 << ' ' << akcje[i].second.second + 1 << endl; } else { cout << "- " << akcje[i].second.first + 1 << ' ' << akcje[i].second.second + 1 << endl; } } return 0; } |