#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; } |