CodeForces-59E.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <queue>
  4. #include <unordered_set>
  5. #include <vector>
  6. using namespace std;
  7. int main() {
  8. ios::sync_with_stdio(false);
  9. cin.tie(nullptr);
  10. int n, m, k; cin >> n >> m >> k;
  11. vector<vector<int>> g(n + 1);
  12. for (int i = 0; i < m; ++i) {
  13. int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u);
  14. }
  15. int width = n + 1;
  16. auto state = [width](int previous, int current) { return previous * width + current; };
  17. auto triple = [width](int a, int b, int c) {
  18. return (static_cast<long long>(a) * width + b) * width + c;
  19. };
  20. unordered_set<long long> forbidden;
  21. forbidden.reserve(static_cast<size_t>(k) * 2 + 1);
  22. while (k--) { int a, b, c; cin >> a >> b >> c; forbidden.insert(triple(a, b, c)); }
  23. int states = width * width;
  24. vector<int> dist(states, -1), parent(states, -1);
  25. int start = state(0, 1), target = -1;
  26. queue<int> q; q.push(start); dist[start] = 0;
  27. while (!q.empty() && target == -1) {
  28. int id = q.front(); q.pop();
  29. int previous = id / width, current = id % width;
  30. for (int next : g[current]) {
  31. if (forbidden.count(triple(previous, current, next))) continue;
  32. int next_state = state(current, next);
  33. if (dist[next_state] != -1) continue;
  34. dist[next_state] = dist[id] + 1;
  35. parent[next_state] = id;
  36. if (next == n) { target = next_state; break; }
  37. q.push(next_state);
  38. }
  39. }
  40. if (target == -1) { cout << "-1\n"; return 0; }
  41. vector<int> path;
  42. for (int id = target; id != -1; id = parent[id]) path.push_back(id % width);
  43. reverse(path.begin(), path.end());
  44. cout << path.size() - 1 << '\n';
  45. for (int v : path) cout << v << ' ';
  46. cout << '\n';
  47. }