#include <bits/stdc++.h> using namespace std; struct node { int id = 0; set<node*> neigh = {}; int visited = 0; static void insert(node* a, node* b) { a->neigh.insert(b); b->neigh.insert(a); } static void erase(node* a, node* b) { a->neigh.erase(b); b->neigh.erase(a); } }; typedef pair<node*, node*> edge; struct change { pair<int, int> edge; bool remove; }; void createOneEdges(node* one, node* root, int visited, set<int>& existing, vector<change>& moves); void eraseOneEdges(node* one, node* root, int visited, set<int>& toKeep, vector<change>& moves); int main() { int n; scanf(" %d", &n); vector<node> nodes(n); for (int i = 0; i < n; i++) { nodes[i].id = i+1; } set<pair<int, int>> toInsert; set<pair<int, int>> toErase; set<int> oneEdgesKeep; set<int> oneEdgesExist; int e; scanf(" %d", &e); for (int i = 0; i < e; i++) { int a, b; scanf(" %d %d", &a, &b); if (a > b) swap(a,b); node::insert(&nodes[a-1],&nodes[b-1]); if (a == 1) { oneEdgesExist.insert(b); } else { toErase.insert({a,b}); } } scanf(" %d", &e); for (int i = 0; i < e; i++) { int a, b; scanf(" %d %d", &a, &b); if (a > b) swap(a,b); if (a == 1) { oneEdgesKeep.insert(b); } else if (toErase.count({a,b})) { toErase.erase({a,b}); } else { toInsert.insert({a,b}); } } vector<change> moves; oneEdgesKeep.insert(1); oneEdgesExist.insert(1); createOneEdges(&nodes[0], &nodes[0], 1, oneEdgesExist, moves); for (auto e : toInsert) { node::insert(&nodes[e.first-1], &nodes[e.second-1]); moves.push_back({e, false}); } for (auto e : toErase) { node::erase(&nodes[e.first-1], &nodes[e.second-1]); moves.push_back({e, true}); } for (int i = 1; i < n; i++) { if (!oneEdgesKeep.count(i+1)) { node::erase(&nodes[0], &nodes[i]); } } eraseOneEdges(&nodes[0], &nodes[0], 2, oneEdgesKeep, moves); printf("%lld\n", moves.size()); for (auto& m : moves) { printf("%c %d %d\n", m.remove ? '-' : '+', m.edge.first, m.edge.second); } } void createOneEdges(node* one, node* root, int visited, set<int>& existing, vector<change>& moves) { if (root->visited == visited) return; root->visited = visited; if (existing.count(root->id) == 0) { node::insert(one, root); moves.push_back({{1, root->id}, false}); } for (auto ngh : root->neigh) { createOneEdges(one, ngh, visited, existing, moves); } } void eraseOneEdges(node* one, node* root, int visited, set<int>& toKeep, vector<change>& moves) { if (root->visited == visited) return; root->visited = visited; for (auto ngh : root->neigh) { eraseOneEdges(one, ngh, visited, toKeep, moves); } if (toKeep.count(root->id) == 0) { moves.push_back({{1, root->id}, true}); } }
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 | #include <bits/stdc++.h> using namespace std; struct node { int id = 0; set<node*> neigh = {}; int visited = 0; static void insert(node* a, node* b) { a->neigh.insert(b); b->neigh.insert(a); } static void erase(node* a, node* b) { a->neigh.erase(b); b->neigh.erase(a); } }; typedef pair<node*, node*> edge; struct change { pair<int, int> edge; bool remove; }; void createOneEdges(node* one, node* root, int visited, set<int>& existing, vector<change>& moves); void eraseOneEdges(node* one, node* root, int visited, set<int>& toKeep, vector<change>& moves); int main() { int n; scanf(" %d", &n); vector<node> nodes(n); for (int i = 0; i < n; i++) { nodes[i].id = i+1; } set<pair<int, int>> toInsert; set<pair<int, int>> toErase; set<int> oneEdgesKeep; set<int> oneEdgesExist; int e; scanf(" %d", &e); for (int i = 0; i < e; i++) { int a, b; scanf(" %d %d", &a, &b); if (a > b) swap(a,b); node::insert(&nodes[a-1],&nodes[b-1]); if (a == 1) { oneEdgesExist.insert(b); } else { toErase.insert({a,b}); } } scanf(" %d", &e); for (int i = 0; i < e; i++) { int a, b; scanf(" %d %d", &a, &b); if (a > b) swap(a,b); if (a == 1) { oneEdgesKeep.insert(b); } else if (toErase.count({a,b})) { toErase.erase({a,b}); } else { toInsert.insert({a,b}); } } vector<change> moves; oneEdgesKeep.insert(1); oneEdgesExist.insert(1); createOneEdges(&nodes[0], &nodes[0], 1, oneEdgesExist, moves); for (auto e : toInsert) { node::insert(&nodes[e.first-1], &nodes[e.second-1]); moves.push_back({e, false}); } for (auto e : toErase) { node::erase(&nodes[e.first-1], &nodes[e.second-1]); moves.push_back({e, true}); } for (int i = 1; i < n; i++) { if (!oneEdgesKeep.count(i+1)) { node::erase(&nodes[0], &nodes[i]); } } eraseOneEdges(&nodes[0], &nodes[0], 2, oneEdgesKeep, moves); printf("%lld\n", moves.size()); for (auto& m : moves) { printf("%c %d %d\n", m.remove ? '-' : '+', m.edge.first, m.edge.second); } } void createOneEdges(node* one, node* root, int visited, set<int>& existing, vector<change>& moves) { if (root->visited == visited) return; root->visited = visited; if (existing.count(root->id) == 0) { node::insert(one, root); moves.push_back({{1, root->id}, false}); } for (auto ngh : root->neigh) { createOneEdges(one, ngh, visited, existing, moves); } } void eraseOneEdges(node* one, node* root, int visited, set<int>& toKeep, vector<change>& moves) { if (root->visited == visited) return; root->visited = visited; for (auto ngh : root->neigh) { eraseOneEdges(one, ngh, visited, toKeep, moves); } if (toKeep.count(root->id) == 0) { moves.push_back({{1, root->id}, true}); } } |