#include <iostream> #include <vector> #include <set> #include <stack> using namespace std; class Vertex { public: int id; set<Vertex*> neighbours; Vertex(int _id) { id = _id; } }; class Graph { public: vector<Vertex*> vertices; int size; Graph(int n) { for(int i = 0; i < n; ++i) { vertices.push_back(new Vertex(i)); } size = n; } bool are_connected(int a, int b) { // is there an edge between a and b return vertices[a]->neighbours.count(vertices[b]) > 0; } vector<pair<int,int>> add_missing(Graph* target) { // Simply adds, assumes all additions are legal vector<pair<int, int>> moves_seq; for(int i = 0; i < target->vertices.size(); ++i) { for(auto t : target->vertices[i]->neighbours) { if(!are_connected(target->vertices[i]->id, t->id)) { moves_seq.push_back(make_pair(target->vertices[i]->id, t->id)); create_edge(target->vertices[i]->id, t->id); } } } return moves_seq; } vector<pair<int,int>> connect_all(int a) { vector<pair<int, int>> moves_seq; bool* visited = new bool[size]; for(int i = 0; i < size; ++i) { visited[i] = false; } stack<Vertex*> s; visited[a] = true; for(auto v : vertices[a]->neighbours) { visited[v->id] = true; s.push(v); } while(!s.empty()) { Vertex* curr = s.top(); s.pop(); for(auto v : curr->neighbours) { if(!visited[v->id]) { visited[v->id] = true; s.push(v); moves_seq.push_back(make_pair(a, v->id)); create_edge(a, v->id); } } } return moves_seq; } void create_edge(int a, int b) { vertices[a]->neighbours.insert(vertices[b]); vertices[b]->neighbours.insert(vertices[a]); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n; int m1; cin >> m1; Graph start(n); int a; int b; for(int i = 0; i < m1; ++i) { cin >> a; --a; cin >> b; --b; start.create_edge(a, b); } int m2; cin >> m2; Graph stop(n); for(int i = 0; i < m2; ++i) { cin >> a; --a; cin >> b; --b; stop.create_edge(a, b); } vector<pair<int, int>> moves_seq1 = start.connect_all(0); //cout << "Adding missing\n"; vector<pair<int, int>> moves_seq2 = start.add_missing(&stop); // Remove all the additional vector<pair<int, int>> moves_seq3 = stop.connect_all(0); vector<pair<int, int>> moves_seq4 = stop.add_missing(&start); cout << moves_seq1.size() + moves_seq2.size() + moves_seq3.size() + moves_seq4.size() << "\n"; for(int i = 0; i < moves_seq1.size(); ++i) { cout << "+ " << moves_seq1[i].first + 1 << " " << moves_seq1[i].second + 1 << "\n"; } for(int i = 0; i < moves_seq2.size(); ++i) { cout << "+ " << moves_seq2[i].first + 1 << " " << moves_seq2[i].second + 1 << "\n"; } for(int i = moves_seq4.size() - 1; i >= 0; --i) { cout << "- " << moves_seq4[i].first + 1 << " " << moves_seq4[i].second + 1 << "\n"; } for(int i = moves_seq3.size() - 1; i >= 0; --i) { cout << "- " << moves_seq3[i].first + 1 << " " << moves_seq3[i].second + 1 << "\n"; } 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include <iostream> #include <vector> #include <set> #include <stack> using namespace std; class Vertex { public: int id; set<Vertex*> neighbours; Vertex(int _id) { id = _id; } }; class Graph { public: vector<Vertex*> vertices; int size; Graph(int n) { for(int i = 0; i < n; ++i) { vertices.push_back(new Vertex(i)); } size = n; } bool are_connected(int a, int b) { // is there an edge between a and b return vertices[a]->neighbours.count(vertices[b]) > 0; } vector<pair<int,int>> add_missing(Graph* target) { // Simply adds, assumes all additions are legal vector<pair<int, int>> moves_seq; for(int i = 0; i < target->vertices.size(); ++i) { for(auto t : target->vertices[i]->neighbours) { if(!are_connected(target->vertices[i]->id, t->id)) { moves_seq.push_back(make_pair(target->vertices[i]->id, t->id)); create_edge(target->vertices[i]->id, t->id); } } } return moves_seq; } vector<pair<int,int>> connect_all(int a) { vector<pair<int, int>> moves_seq; bool* visited = new bool[size]; for(int i = 0; i < size; ++i) { visited[i] = false; } stack<Vertex*> s; visited[a] = true; for(auto v : vertices[a]->neighbours) { visited[v->id] = true; s.push(v); } while(!s.empty()) { Vertex* curr = s.top(); s.pop(); for(auto v : curr->neighbours) { if(!visited[v->id]) { visited[v->id] = true; s.push(v); moves_seq.push_back(make_pair(a, v->id)); create_edge(a, v->id); } } } return moves_seq; } void create_edge(int a, int b) { vertices[a]->neighbours.insert(vertices[b]); vertices[b]->neighbours.insert(vertices[a]); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n; int m1; cin >> m1; Graph start(n); int a; int b; for(int i = 0; i < m1; ++i) { cin >> a; --a; cin >> b; --b; start.create_edge(a, b); } int m2; cin >> m2; Graph stop(n); for(int i = 0; i < m2; ++i) { cin >> a; --a; cin >> b; --b; stop.create_edge(a, b); } vector<pair<int, int>> moves_seq1 = start.connect_all(0); //cout << "Adding missing\n"; vector<pair<int, int>> moves_seq2 = start.add_missing(&stop); // Remove all the additional vector<pair<int, int>> moves_seq3 = stop.connect_all(0); vector<pair<int, int>> moves_seq4 = stop.add_missing(&start); cout << moves_seq1.size() + moves_seq2.size() + moves_seq3.size() + moves_seq4.size() << "\n"; for(int i = 0; i < moves_seq1.size(); ++i) { cout << "+ " << moves_seq1[i].first + 1 << " " << moves_seq1[i].second + 1 << "\n"; } for(int i = 0; i < moves_seq2.size(); ++i) { cout << "+ " << moves_seq2[i].first + 1 << " " << moves_seq2[i].second + 1 << "\n"; } for(int i = moves_seq4.size() - 1; i >= 0; --i) { cout << "- " << moves_seq4[i].first + 1 << " " << moves_seq4[i].second + 1 << "\n"; } for(int i = moves_seq3.size() - 1; i >= 0; --i) { cout << "- " << moves_seq3[i].first + 1 << " " << moves_seq3[i].second + 1 << "\n"; } return 0; } |