AtCoder-agc018_f.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct Edge {
  4. int to;
  5. int id;
  6. };
  7. int main() {
  8. ios::sync_with_stdio(false);
  9. cin.tie(nullptr);
  10. int n;
  11. cin >> n;
  12. vector<int> parent_a(n), parent_b(n);
  13. for (int &x : parent_a) {
  14. cin >> x;
  15. if (x != -1) --x;
  16. }
  17. for (int &x : parent_b) {
  18. cin >> x;
  19. if (x != -1) --x;
  20. }
  21. vector<int> children_a(n), children_b(n);
  22. int root_a = -1, root_b = -1;
  23. for (int v = 0; v < n; ++v) {
  24. if (parent_a[v] == -1) root_a = v;
  25. else ++children_a[parent_a[v]];
  26. if (parent_b[v] == -1) root_b = v;
  27. else ++children_b[parent_b[v]];
  28. }
  29. for (int v = 0; v < n; ++v) {
  30. if ((children_a[v] & 1) != (children_b[v] & 1)) {
  31. cout << "IMPOSSIBLE\n";
  32. return 0;
  33. }
  34. }
  35. const int extra = 2 * n;
  36. vector<vector<Edge>> graph(2 * n + 1);
  37. vector<pair<int, int>> endpoints;
  38. vector<int> cross_vertex;
  39. auto add_edge = [&](int u, int v, int owner) {
  40. int id = static_cast<int>(endpoints.size());
  41. endpoints.push_back({u, v});
  42. cross_vertex.push_back(owner);
  43. graph[u].push_back({v, id});
  44. graph[v].push_back({u, id});
  45. };
  46. for (int v = 0; v < n; ++v) {
  47. if (parent_a[v] != -1) add_edge(v, parent_a[v], -1);
  48. if (parent_b[v] != -1) add_edge(n + v, n + parent_b[v], -1);
  49. }
  50. add_edge(root_a, extra, -1);
  51. add_edge(n + root_b, extra, -1);
  52. for (int v = 0; v < n; ++v) {
  53. if ((children_a[v] & 1) == 0) add_edge(v, n + v, v);
  54. }
  55. vector<int> answer(n, 0), cursor(graph.size(), 0), stack = {extra};
  56. vector<char> used(endpoints.size(), false);
  57. while (!stack.empty()) {
  58. int v = stack.back();
  59. while (cursor[v] < static_cast<int>(graph[v].size()) &&
  60. used[graph[v][cursor[v]].id]) {
  61. ++cursor[v];
  62. }
  63. if (cursor[v] == static_cast<int>(graph[v].size())) {
  64. stack.pop_back();
  65. continue;
  66. }
  67. Edge e = graph[v][cursor[v]++];
  68. if (used[e.id]) continue;
  69. used[e.id] = true;
  70. int owner = cross_vertex[e.id];
  71. if (owner != -1) answer[owner] = (v == owner ? 1 : -1);
  72. stack.push_back(e.to);
  73. }
  74. cout << "POSSIBLE\n";
  75. for (int i = 0; i < n; ++i) {
  76. if (i) cout << ' ';
  77. cout << answer[i];
  78. }
  79. cout << '\n';
  80. return 0;
  81. }