#include #include #include #include #include // day, person using State = std::pair; namespace std { template <> struct hash { size_t operator()(State v) const { // do something smarter here return v.first + 13 * v.second; } }; } template T& checkMax(T& a, T b) { return a = std::max(a, b); } int main() { int32_t n, k, c; std::cin >> n >> k >> c; std::vector>> connections(k + 1, std::vector>(n)); // The earliest day they could have gotten sick. std::vector earliestSick(n, -1); for (int32_t i = 0; i < c; ++i) { int32_t u, v, day; std::cin >> u >> v >> day; --u; --v; --day; connections[day][u].push_back(v); connections[day][v].push_back(u); checkMax(earliestSick[u], day - 1); checkMax(earliestSick[v], day - 1); } // General idea. Try each person as the source. Build a directed graph on // tuples of (day, person). bool isValid = false; std::vector shouldTell(n, false); for (int32_t src = 0; src < n; ++src) { if (earliestSick[src] > -1) { continue; } std::queue q; std::unordered_set seen; std::vector canSick(n, false); q.emplace(-1, src); seen.emplace(-1, src); while (!q.empty()) { auto [day, u] = q.front(); q.pop(); canSick[u] = true; for (int32_t v : connections[day + 1][u]) { if (earliestSick[v] <= day + 1) { State nxt{day + 1, v}; bool isNew = seen.insert(nxt).second; if (isNew) { q.push(nxt); } } } } // only tell people who can get infected on the last day isValid = true; for (auto [day, u] : seen) { if (day + 1 == k) { shouldTell[u] = true; } } } if (isValid) { int32_t toTell = 0; for (bool tell : shouldTell) { toTell += tell; } std::cout << toTell << '\n'; for (int32_t u = 0; u < n; ++u) { if (shouldTell[u]) { std::cout << (u + 1) << '\n'; } } } else { std::cout << -1 << '\n'; } return 0; }