#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
#include <utility>
int n;
int ms, md;
std::vector<std::vector<int>> graph;
std::vector<std::vector<int>> wanted;
std::vector<std::pair<int,int>> edges_s;
std::vector<std::pair<int,int>> edges_d;
std::vector<std::tuple<char,int,int>> ops;
std::vector<int> toposort;
std::vector<bool> visited;
bool is_edge_s(int a, int b) {
return std::binary_search(edges_s.begin(), edges_s.end(), std::pair<int,int>{a, b});
}
bool is_edge_d(int a, int b) {
return std::binary_search(edges_d.begin(), edges_d.end(), std::pair<int,int>{a, b});
}
void dfs_topo(int x, const std::vector<std::vector<int>> &G) {
visited[x] = true;
for (int y : G[x]) {
if (visited[y]) continue;
dfs_topo(y, G);
}
toposort.push_back(x);
}
int main() {
std::ios_base::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0);
std::cin >> n;
graph.assign(n, {});
std::cin >> ms;
edges_s.resize(ms);
for (int i = 0; i < ms; ++i) {
int a, b;
std::cin >> a >> b;
--a; --b;
if (a > b) std::swap(a, b);
edges_s[i] = {a, b};
graph[a].push_back(b);
graph[b].push_back(a);
}
std::sort(edges_s.begin(), edges_s.end());
toposort.clear();
visited.assign(n, false);
dfs_topo(0, graph);
std::reverse(toposort.begin(), toposort.end());
// std::cout << "toposort:";
// for (int v : toposort) std::cout << ' ' << v;
// std::cout << '\n';
for (int i = 1; i < n; ++i) {
int v = toposort[i];
if (is_edge_s(0, v)) continue;
ops.emplace_back('+', 0, v);
graph[0].push_back(v);
graph[v].push_back(0);
}
std::cin >> md;
edges_d.reserve(md);
wanted.assign(n, {});
for (int i = 0; i < md; ++i) {
int a, b;
std::cin >> a >> b;
--a; --b;
if (a > b) std::swap(a, b);
wanted[a].push_back(b);
wanted[b].push_back(a);
edges_d.emplace_back(a, b);
if (a == 0 || is_edge_s(a, b)) continue;
ops.emplace_back('+', a, b);
}
std::sort(edges_d.begin(), edges_d.end());
toposort.clear();
visited.assign(n, false);
dfs_topo(0, wanted);
// std::cout << "toposort:";
// for (int v : toposort) std::cout << ' ' << v;
// std::cout << '\n';
visited.assign(n, false);
for (int i = 0; i < n-1; ++i) {
int v = toposort[i];
visited[v] = true;
for (int y : graph[v]) {
if (visited[y] || y == 0) continue;
int a = v;
int b = y;
if (a > b) std::swap(a, b);
if (!is_edge_d(a, b)) {
ops.emplace_back('-', a, b);
}
}
if (!is_edge_d(0, v)) {
ops.emplace_back('-', 0, v);
}
}
std::cout << ops.size() << '\n';
for (auto [op, a, b] : ops) {
std::cout << op << ' ' << a+1 << ' ' << b+1 << '\n';
}
}
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 | #include <iostream> #include <algorithm> #include <vector> #include <tuple> #include <utility> int n; int ms, md; std::vector<std::vector<int>> graph; std::vector<std::vector<int>> wanted; std::vector<std::pair<int,int>> edges_s; std::vector<std::pair<int,int>> edges_d; std::vector<std::tuple<char,int,int>> ops; std::vector<int> toposort; std::vector<bool> visited; bool is_edge_s(int a, int b) { return std::binary_search(edges_s.begin(), edges_s.end(), std::pair<int,int>{a, b}); } bool is_edge_d(int a, int b) { return std::binary_search(edges_d.begin(), edges_d.end(), std::pair<int,int>{a, b}); } void dfs_topo(int x, const std::vector<std::vector<int>> &G) { visited[x] = true; for (int y : G[x]) { if (visited[y]) continue; dfs_topo(y, G); } toposort.push_back(x); } int main() { std::ios_base::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cin >> n; graph.assign(n, {}); std::cin >> ms; edges_s.resize(ms); for (int i = 0; i < ms; ++i) { int a, b; std::cin >> a >> b; --a; --b; if (a > b) std::swap(a, b); edges_s[i] = {a, b}; graph[a].push_back(b); graph[b].push_back(a); } std::sort(edges_s.begin(), edges_s.end()); toposort.clear(); visited.assign(n, false); dfs_topo(0, graph); std::reverse(toposort.begin(), toposort.end()); // std::cout << "toposort:"; // for (int v : toposort) std::cout << ' ' << v; // std::cout << '\n'; for (int i = 1; i < n; ++i) { int v = toposort[i]; if (is_edge_s(0, v)) continue; ops.emplace_back('+', 0, v); graph[0].push_back(v); graph[v].push_back(0); } std::cin >> md; edges_d.reserve(md); wanted.assign(n, {}); for (int i = 0; i < md; ++i) { int a, b; std::cin >> a >> b; --a; --b; if (a > b) std::swap(a, b); wanted[a].push_back(b); wanted[b].push_back(a); edges_d.emplace_back(a, b); if (a == 0 || is_edge_s(a, b)) continue; ops.emplace_back('+', a, b); } std::sort(edges_d.begin(), edges_d.end()); toposort.clear(); visited.assign(n, false); dfs_topo(0, wanted); // std::cout << "toposort:"; // for (int v : toposort) std::cout << ' ' << v; // std::cout << '\n'; visited.assign(n, false); for (int i = 0; i < n-1; ++i) { int v = toposort[i]; visited[v] = true; for (int y : graph[v]) { if (visited[y] || y == 0) continue; int a = v; int b = y; if (a > b) std::swap(a, b); if (!is_edge_d(a, b)) { ops.emplace_back('-', a, b); } } if (!is_edge_d(0, v)) { ops.emplace_back('-', 0, v); } } std::cout << ops.size() << '\n'; for (auto [op, a, b] : ops) { std::cout << op << ' ' << a+1 << ' ' << b+1 << '\n'; } } |
English