#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
struct graph {
struct edge {
int vert;
int next;
edge(int vert, int next) : vert(vert), next(next) {}
};
std::vector<int> firsts;
std::vector<edge> edges;
graph(int count) {
firsts.resize(count, -1);
}
graph(graph&&) = default;
graph(const graph&) = delete;
graph& operator=(graph&&) = default;
graph& operator=(const graph&) = delete;
void add_edge(int from, int to) {
int idx = edges.size();
edges.push_back(edge(to, firsts[from]));
firsts[from] = idx;
}
template<typename F>
void for_each_neighbor(int v, F f) const {
for (int e = firsts[v]; e != -1; e = edges[e].next) {
f(edges[e].vert);
}
}
};
std::pair<graph, std::vector<std::pair<int, int> > > load_graph(int n, int m) {
graph g(n);
std::vector<std::pair<int, int> > edges;
for (int i = 0; i < m; i++) {
int a, b;
scanf("%d %d", &a, &b);
g.add_edge(a - 1, b - 1);
g.add_edge(b - 1, a - 1);
if (a != 1 && b != 1) {
edges.push_back({a - 1, b - 1});
}
}
return std::make_pair<graph, std::vector<std::pair<int, int> > >(std::move(g), std::move(edges));
}
std::vector<std::pair<int, int> > bfs(const graph& g, int n) {
std::vector<std::pair<int, int> > ret;
std::vector<bool> visited(n);
int qpos = 0;
visited[0] = true;
g.for_each_neighbor(0, [&] (int v) {
ret.push_back(std::pair(0, v));
visited[v] = true;
});
int to_drop = ret.size();
while (qpos < ret.size()) {
auto [parent, v] = ret[qpos++];
g.for_each_neighbor(v, [&] (int x) {
if (visited[x]) {
return;
}
ret.push_back(std::pair(0, x));
visited[x] = true;
});
}
ret.erase(ret.begin(), ret.begin() + to_drop);
return ret;
}
int main() {
int n, m1, m2;
scanf("%d", &n);
scanf("%d", &m1);
auto [source_g, source_edges] = load_graph(n, m1);
auto source_bfs = bfs(source_g, n);
scanf("%d", &m2);
auto [dest_g, dest_edges] = load_graph(n, m2);
auto dest_bfs = bfs(dest_g, n);
std::reverse(dest_bfs.begin(), dest_bfs.end());
const int nmoves = source_bfs.size() + source_edges.size()
+ dest_edges.size() + dest_bfs.size();
printf("%d\n", nmoves);
auto print_commands = [] (char op, const std::vector<std::pair<int, int> >& v) {
for (auto [a, b] : v) {
printf("%c %d %d\n", op, a + 1, b + 1);
}
};
print_commands('+', source_bfs);
print_commands('-', source_edges);
print_commands('+', dest_edges);
print_commands('-', dest_bfs);
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 | #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> struct graph { struct edge { int vert; int next; edge(int vert, int next) : vert(vert), next(next) {} }; std::vector<int> firsts; std::vector<edge> edges; graph(int count) { firsts.resize(count, -1); } graph(graph&&) = default; graph(const graph&) = delete; graph& operator=(graph&&) = default; graph& operator=(const graph&) = delete; void add_edge(int from, int to) { int idx = edges.size(); edges.push_back(edge(to, firsts[from])); firsts[from] = idx; } template<typename F> void for_each_neighbor(int v, F f) const { for (int e = firsts[v]; e != -1; e = edges[e].next) { f(edges[e].vert); } } }; std::pair<graph, std::vector<std::pair<int, int> > > load_graph(int n, int m) { graph g(n); std::vector<std::pair<int, int> > edges; for (int i = 0; i < m; i++) { int a, b; scanf("%d %d", &a, &b); g.add_edge(a - 1, b - 1); g.add_edge(b - 1, a - 1); if (a != 1 && b != 1) { edges.push_back({a - 1, b - 1}); } } return std::make_pair<graph, std::vector<std::pair<int, int> > >(std::move(g), std::move(edges)); } std::vector<std::pair<int, int> > bfs(const graph& g, int n) { std::vector<std::pair<int, int> > ret; std::vector<bool> visited(n); int qpos = 0; visited[0] = true; g.for_each_neighbor(0, [&] (int v) { ret.push_back(std::pair(0, v)); visited[v] = true; }); int to_drop = ret.size(); while (qpos < ret.size()) { auto [parent, v] = ret[qpos++]; g.for_each_neighbor(v, [&] (int x) { if (visited[x]) { return; } ret.push_back(std::pair(0, x)); visited[x] = true; }); } ret.erase(ret.begin(), ret.begin() + to_drop); return ret; } int main() { int n, m1, m2; scanf("%d", &n); scanf("%d", &m1); auto [source_g, source_edges] = load_graph(n, m1); auto source_bfs = bfs(source_g, n); scanf("%d", &m2); auto [dest_g, dest_edges] = load_graph(n, m2); auto dest_bfs = bfs(dest_g, n); std::reverse(dest_bfs.begin(), dest_bfs.end()); const int nmoves = source_bfs.size() + source_edges.size() + dest_edges.size() + dest_bfs.size(); printf("%d\n", nmoves); auto print_commands = [] (char op, const std::vector<std::pair<int, int> >& v) { for (auto [a, b] : v) { printf("%c %d %d\n", op, a + 1, b + 1); } }; print_commands('+', source_bfs); print_commands('-', source_edges); print_commands('+', dest_edges); print_commands('-', dest_bfs); return 0; } |
English