#include <bits/stdc++.h> using namespace std; #define rep(a, b) for (int a = 0; a < (b); a++) #define rep1(a, b) for (int a = 1; a <= (b); a++) #define all(x) (x).begin(), (x).end() using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; const int MOD = 1e9 + 7; #define LOCAL false const int MAX_V = 3e4 + 7; const int MAX_E = 5e4 + 7; int V, E1, E2; set<pii> edges1, edges2; vector<int> graph[MAX_V]; vector<pair<int, pii>> ans; void add(int v1, int v2) { if (v1 > v2) swap(v1, v2); ans.push_back({1, {v1, v2}}); // debug // if (edges1.count({v1, v2})) { // cout << "XD\n"; // return; // } // bool ok = false; // rep1(vmid, V) if (vmid != v1 && vmid != v2) // ok |= (edges1.count({min(v1, vmid), max(v1, vmid)}) && edges1.count({min(v2, vmid), max(v2, vmid)})); // if (!ok) { // cout << "XD\n"; // return; // } // ----- edges1.insert({v1, v2}); graph[v1].push_back(v2); graph[v2].push_back(v1); } void remove(int v1, int v2) { if (v1 > v2) swap(v1, v2); ans.push_back({2, {v1, v2}}); // debug // cnt++; // if (!edges1.count({v1, v2})) { // cout << "XD1\n"; // return; // } // bool ok = false; // rep1(vmid, V) if (vmid != v1 && vmid != v2) // ok |= (edges1.count({min(v1, vmid), max(v1, vmid)}) && edges1.count({min(v2, vmid), max(v2, vmid)})); // if (!ok) { // cout << "XD2\n"; // return; // } // ----- edges1.erase({v1, v2}); } bool vis[MAX_V]; void dfs(int v) { // cout << "dfs(" << v << ")\n"; vis[v] = true; vector<int> toadd; if (!edges1.count({1, v}) && v != 1) toadd.push_back(v); for (int v: toadd) add(1, v); vector<int> togo; for (int to: graph[v]) if (!vis[to]) togo.push_back(to); for (int to: togo) dfs(to); } bool vis2[MAX_V]; void dfs2(int v, bool root = true) { // cout << "dfs2(" << v << ' ' << root << ")\n"; vis2[v] = true; for (int to: graph[v]) if (!vis2[to] && edges1.count({min(v, to), max(v, to)})) dfs2(to, false); if (!root && !edges2.count({1, v})) remove(1, v); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); if (LOCAL) { ignore=freopen("io/in", "r", stdin); ignore=freopen("io/out", "w", stdout); } cin >> V; cin >> E1; int v1, v2; rep(i, E1) { cin >> v1 >> v2; if (v1 > v2) swap(v1, v2); edges1.insert({v1, v2}); graph[v1].push_back(v2); graph[v2].push_back(v1); } cin >> E2; rep(i, E2) { cin >> v1 >> v2; if (v1 > v2) swap(v1, v2); edges2.insert({v1, v2}); } dfs(1); for (pii e: edges2) if (!edges1.count(e)) add(e.first, e.second); set<pii> edges1cpy = edges1; for (pii e: edges1cpy) if (e.first != 1 && !edges2.count(e)) remove(e.first, e.second); vis2[1] = true; edges1cpy = edges1; for (auto [v1, v2]: edges1cpy) if (v1 == 1 && !vis2[v2] && edges2.count({1, v2})) dfs2(v2); // if (edges1 == edges2) cout << "GIT\n"; cout << ans.size() << '\n'; for (auto [mode, p]: ans) cout << (mode == 1 ? "+ " : "- ") << p.first << ' ' << p.second << '\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 | #include <bits/stdc++.h> using namespace std; #define rep(a, b) for (int a = 0; a < (b); a++) #define rep1(a, b) for (int a = 1; a <= (b); a++) #define all(x) (x).begin(), (x).end() using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; const int MOD = 1e9 + 7; #define LOCAL false const int MAX_V = 3e4 + 7; const int MAX_E = 5e4 + 7; int V, E1, E2; set<pii> edges1, edges2; vector<int> graph[MAX_V]; vector<pair<int, pii>> ans; void add(int v1, int v2) { if (v1 > v2) swap(v1, v2); ans.push_back({1, {v1, v2}}); // debug // if (edges1.count({v1, v2})) { // cout << "XD\n"; // return; // } // bool ok = false; // rep1(vmid, V) if (vmid != v1 && vmid != v2) // ok |= (edges1.count({min(v1, vmid), max(v1, vmid)}) && edges1.count({min(v2, vmid), max(v2, vmid)})); // if (!ok) { // cout << "XD\n"; // return; // } // ----- edges1.insert({v1, v2}); graph[v1].push_back(v2); graph[v2].push_back(v1); } void remove(int v1, int v2) { if (v1 > v2) swap(v1, v2); ans.push_back({2, {v1, v2}}); // debug // cnt++; // if (!edges1.count({v1, v2})) { // cout << "XD1\n"; // return; // } // bool ok = false; // rep1(vmid, V) if (vmid != v1 && vmid != v2) // ok |= (edges1.count({min(v1, vmid), max(v1, vmid)}) && edges1.count({min(v2, vmid), max(v2, vmid)})); // if (!ok) { // cout << "XD2\n"; // return; // } // ----- edges1.erase({v1, v2}); } bool vis[MAX_V]; void dfs(int v) { // cout << "dfs(" << v << ")\n"; vis[v] = true; vector<int> toadd; if (!edges1.count({1, v}) && v != 1) toadd.push_back(v); for (int v: toadd) add(1, v); vector<int> togo; for (int to: graph[v]) if (!vis[to]) togo.push_back(to); for (int to: togo) dfs(to); } bool vis2[MAX_V]; void dfs2(int v, bool root = true) { // cout << "dfs2(" << v << ' ' << root << ")\n"; vis2[v] = true; for (int to: graph[v]) if (!vis2[to] && edges1.count({min(v, to), max(v, to)})) dfs2(to, false); if (!root && !edges2.count({1, v})) remove(1, v); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); if (LOCAL) { ignore=freopen("io/in", "r", stdin); ignore=freopen("io/out", "w", stdout); } cin >> V; cin >> E1; int v1, v2; rep(i, E1) { cin >> v1 >> v2; if (v1 > v2) swap(v1, v2); edges1.insert({v1, v2}); graph[v1].push_back(v2); graph[v2].push_back(v1); } cin >> E2; rep(i, E2) { cin >> v1 >> v2; if (v1 > v2) swap(v1, v2); edges2.insert({v1, v2}); } dfs(1); for (pii e: edges2) if (!edges1.count(e)) add(e.first, e.second); set<pii> edges1cpy = edges1; for (pii e: edges1cpy) if (e.first != 1 && !edges2.count(e)) remove(e.first, e.second); vis2[1] = true; edges1cpy = edges1; for (auto [v1, v2]: edges1cpy) if (v1 == 1 && !vis2[v2] && edges2.count({1, v2})) dfs2(v2); // if (edges1 == edges2) cout << "GIT\n"; cout << ans.size() << '\n'; for (auto [mode, p]: ans) cout << (mode == 1 ? "+ " : "- ") << p.first << ' ' << p.second << '\n'; return 0; } |