#include <bits/stdc++.h>
using namespace std;
const int N = 30'000 + 7;
int n, m1, m2;
vector<int> adj1[N], adj2[N];
set<pair<int, int>> edges1;
set<pair<int, int>> edges2;
set<pair<int, int>> edges;
int vis[N], col;
vector<tuple<char, int, int>> ans;
void dfs1(int u, int mode) {
vis[u] = col;
if (u != 1 && mode == +1) {
if (edges.count(make_pair(1, u)) == 0) {
ans.emplace_back('+', 1, u);
edges.emplace(1, u);
edges.emplace(u, 1);
}
}
for (int v : adj1[u]) {
if (vis[v] != col) {
dfs1(v, mode);
}
}
/*
if (u != 1 && mode == -1) {
assert(edges.count(make_pair(1, u)));
if (edges1.count(make_pair(1, u)) == 0 &&
edges2.count(make_pair(1, u)) == 0) {
ans.emplace_back('-', 1, u);
edges.erase(make_pair(1, u));
edges.erase(make_pair(u, 1));
}
}
*/
}
void dfs2(int u, int mode) {
vis[u] = col;
/*
if (u != 1 && mode == +1) {
if (edges.count(make_pair(1, u)) == 0) {
ans.emplace_back('+', 1, u);
edges.emplace(1, u);
edges.emplace(u, 1);
}
}
*/
for (int v : adj2[u]) {
if (vis[v] != col) {
dfs2(v, mode);
}
}
if (u != 1 && mode == -1) {
assert(edges.count(make_pair(1, u)));
if (edges2.count(make_pair(1, u)) == 0) {
ans.emplace_back('-', 1, u);
edges.erase(make_pair(1, u));
edges.erase(make_pair(u, 1));
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n;
cin >> m1;
for (int i = 1; i <= m1; i++) {
int a, b;
cin >> a >> b;
adj1[a].push_back(b);
adj1[b].push_back(a);
edges1.emplace(a, b);
edges1.emplace(b, a);
}
cin >> m2;
for (int i = 1; i <= m2; i++) {
int a, b;
cin >> a >> b;
adj2[a].push_back(b);
adj2[b].push_back(a);
edges2.emplace(a, b);
edges2.emplace(b, a);
}
edges = edges1;
col++;
dfs1(1, +1);
for (auto&& [a, b] : edges2) {
if (edges.count(make_pair(a, b)) == 0) {
ans.emplace_back('+', a, b);
edges.emplace(a, b);
edges.emplace(b, a);
}
}
/*
col++;
dfs1(1, -1);
col++;
dfs2(1, +1);
*/
for (auto&& [a, b] : edges1) {
if (edges.count(make_pair(a, b)) > 0 &&
edges2.count(make_pair(a, b)) == 0 &&
a != 1 && b != 1) {
ans.emplace_back('-', a, b);
edges.erase(make_pair(a, b));
edges.erase(make_pair(b, a));
}
}
col++;
dfs2(1, -1);
cerr << "ans: " << ans.size() << '\n';
assert((int) ans.size() <= 200'000);
cout << ans.size() << '\n';
for (auto&& [c, a, b] : ans)
cout << c << ' ' << a << ' ' << b << '\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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | #include <bits/stdc++.h> using namespace std; const int N = 30'000 + 7; int n, m1, m2; vector<int> adj1[N], adj2[N]; set<pair<int, int>> edges1; set<pair<int, int>> edges2; set<pair<int, int>> edges; int vis[N], col; vector<tuple<char, int, int>> ans; void dfs1(int u, int mode) { vis[u] = col; if (u != 1 && mode == +1) { if (edges.count(make_pair(1, u)) == 0) { ans.emplace_back('+', 1, u); edges.emplace(1, u); edges.emplace(u, 1); } } for (int v : adj1[u]) { if (vis[v] != col) { dfs1(v, mode); } } /* if (u != 1 && mode == -1) { assert(edges.count(make_pair(1, u))); if (edges1.count(make_pair(1, u)) == 0 && edges2.count(make_pair(1, u)) == 0) { ans.emplace_back('-', 1, u); edges.erase(make_pair(1, u)); edges.erase(make_pair(u, 1)); } } */ } void dfs2(int u, int mode) { vis[u] = col; /* if (u != 1 && mode == +1) { if (edges.count(make_pair(1, u)) == 0) { ans.emplace_back('+', 1, u); edges.emplace(1, u); edges.emplace(u, 1); } } */ for (int v : adj2[u]) { if (vis[v] != col) { dfs2(v, mode); } } if (u != 1 && mode == -1) { assert(edges.count(make_pair(1, u))); if (edges2.count(make_pair(1, u)) == 0) { ans.emplace_back('-', 1, u); edges.erase(make_pair(1, u)); edges.erase(make_pair(u, 1)); } } } int main() { ios::sync_with_stdio(false), cin.tie(nullptr); cin >> n; cin >> m1; for (int i = 1; i <= m1; i++) { int a, b; cin >> a >> b; adj1[a].push_back(b); adj1[b].push_back(a); edges1.emplace(a, b); edges1.emplace(b, a); } cin >> m2; for (int i = 1; i <= m2; i++) { int a, b; cin >> a >> b; adj2[a].push_back(b); adj2[b].push_back(a); edges2.emplace(a, b); edges2.emplace(b, a); } edges = edges1; col++; dfs1(1, +1); for (auto&& [a, b] : edges2) { if (edges.count(make_pair(a, b)) == 0) { ans.emplace_back('+', a, b); edges.emplace(a, b); edges.emplace(b, a); } } /* col++; dfs1(1, -1); col++; dfs2(1, +1); */ for (auto&& [a, b] : edges1) { if (edges.count(make_pair(a, b)) > 0 && edges2.count(make_pair(a, b)) == 0 && a != 1 && b != 1) { ans.emplace_back('-', a, b); edges.erase(make_pair(a, b)); edges.erase(make_pair(b, a)); } } col++; dfs2(1, -1); cerr << "ans: " << ans.size() << '\n'; assert((int) ans.size() <= 200'000); cout << ans.size() << '\n'; for (auto&& [c, a, b] : ans) cout << c << ' ' << a << ' ' << b << '\n'; return 0; } |
English