#include <bits/stdc++.h> #define int long long using namespace std; const int maxn = 2e5+1; int m; bool usedd[maxn]; bool iscut[maxn]; int h[maxn], d[maxn]; set <int> mset; vector <string> ans; void dfs(int v, vector <vector <int>> &g, int p = -1) { usedd[v] = 1; d[v] = h[v] = (p == -1 ? 0 : h[p] + 1); int children = 0; for (int u : g[v]) { if (u != p) { if (usedd[u]) d[v] = min(d[v], h[u]); else { dfs(u, g, p); d[v] = min(d[v], d[u]); if (h[v] <= d[u] && p != -1) { iscut[v] = 1; } children++; } } } if (p == -1 && children > 1) { iscut[v] = 1; } } vector<char> used; void dfs1 (int v, vector <vector <int>> &g, vector <vector <int>> &t) { used[v] = true; for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i){ if(!mset.count(*i) and *i != m) { ans.push_back('+' + to_string(*i+1) + " " + to_string(m+1)); mset.insert(*i); t[m].push_back(*i); t[*i].push_back(m); } if (!used[*i]) dfs1 (*i, g, t); } } set <pair <int, int>> msett; void dfs2 (int v, vector <vector <int>> &g, int p = -1) { used[v] = true; for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i) if (!used[*i]) dfs2(*i, g, v); pair <int, int> pp = {m, v}; if(p!=m and msett.count(pp)==0) ans.push_back("- " + to_string(m+1) + " " + to_string(v+1)); } int32_t main() { ios::sync_with_stdio(0); cin.tie(0); int n, m1, m2; cin >> n >> m1; vector <vector <int>> v1(n), v2(n); for(int i = 0; i < m1; i++){ int x, y; cin >> x >> y; x--; y--; v1[x].push_back(y); v1[y].push_back(x); } cin >> m2; for(int i = 0; i < m2; i++){ int x, y; cin >> x >> y; x--; y--; v2[x].push_back(y); v2[y].push_back(x); } dfs(0, v2); m = 0; vector <vector <int>> t(n); t = v1; for(int i = 0; i < n; i++) { if(!iscut[i]){ m = i; break; } } for(auto x: v1[m]) mset.insert(x); used.resize(n); dfs1(m, v1, t); set <pair <int,int>> e; for(int i = 0; i < n; i++) for(auto to: v2[i]) if(to != m and i != m) e.insert({min(i, to), max(i, to)}); set <pair <int,int>> d; for(int i = 0; i < n; i++) for(auto to: v1[i]) if(e.count({min(i, to), max(i, to)}) == 0 and to != m and i != m) d.insert({min(i, to), max(i, to)}); for(auto [a, b] : d) if(a != b) ans.push_back("- " + to_string(a+1) + " " + to_string(b+1)); used.clear(); used.resize(n); msett.clear(); msett.insert({m, m}); for(auto x: v1[m]) msett.insert({m, x}); dfs2(m,v2); cout << ans.size() << "\n"; for(auto x: ans) cout << x << "\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 | #include <bits/stdc++.h> #define int long long using namespace std; const int maxn = 2e5+1; int m; bool usedd[maxn]; bool iscut[maxn]; int h[maxn], d[maxn]; set <int> mset; vector <string> ans; void dfs(int v, vector <vector <int>> &g, int p = -1) { usedd[v] = 1; d[v] = h[v] = (p == -1 ? 0 : h[p] + 1); int children = 0; for (int u : g[v]) { if (u != p) { if (usedd[u]) d[v] = min(d[v], h[u]); else { dfs(u, g, p); d[v] = min(d[v], d[u]); if (h[v] <= d[u] && p != -1) { iscut[v] = 1; } children++; } } } if (p == -1 && children > 1) { iscut[v] = 1; } } vector<char> used; void dfs1 (int v, vector <vector <int>> &g, vector <vector <int>> &t) { used[v] = true; for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i){ if(!mset.count(*i) and *i != m) { ans.push_back('+' + to_string(*i+1) + " " + to_string(m+1)); mset.insert(*i); t[m].push_back(*i); t[*i].push_back(m); } if (!used[*i]) dfs1 (*i, g, t); } } set <pair <int, int>> msett; void dfs2 (int v, vector <vector <int>> &g, int p = -1) { used[v] = true; for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i) if (!used[*i]) dfs2(*i, g, v); pair <int, int> pp = {m, v}; if(p!=m and msett.count(pp)==0) ans.push_back("- " + to_string(m+1) + " " + to_string(v+1)); } int32_t main() { ios::sync_with_stdio(0); cin.tie(0); int n, m1, m2; cin >> n >> m1; vector <vector <int>> v1(n), v2(n); for(int i = 0; i < m1; i++){ int x, y; cin >> x >> y; x--; y--; v1[x].push_back(y); v1[y].push_back(x); } cin >> m2; for(int i = 0; i < m2; i++){ int x, y; cin >> x >> y; x--; y--; v2[x].push_back(y); v2[y].push_back(x); } dfs(0, v2); m = 0; vector <vector <int>> t(n); t = v1; for(int i = 0; i < n; i++) { if(!iscut[i]){ m = i; break; } } for(auto x: v1[m]) mset.insert(x); used.resize(n); dfs1(m, v1, t); set <pair <int,int>> e; for(int i = 0; i < n; i++) for(auto to: v2[i]) if(to != m and i != m) e.insert({min(i, to), max(i, to)}); set <pair <int,int>> d; for(int i = 0; i < n; i++) for(auto to: v1[i]) if(e.count({min(i, to), max(i, to)}) == 0 and to != m and i != m) d.insert({min(i, to), max(i, to)}); for(auto [a, b] : d) if(a != b) ans.push_back("- " + to_string(a+1) + " " + to_string(b+1)); used.clear(); used.resize(n); msett.clear(); msett.insert({m, m}); for(auto x: v1[m]) msett.insert({m, x}); dfs2(m,v2); cout << ans.size() << "\n"; for(auto x: ans) cout << x << "\n"; return 0; } |