Submission #1222070

#TimeUsernameProblemLanguageResultExecution timeMemory
1222070totoroThousands Islands (IOI22_islands)C++20
1.75 / 100
1151 ms1953432 KiB
#include "islands.h" #include <iostream> #include <map> #include <variant> #include <vector> std::variant<bool, std::vector<int>> find_journey_connected(int N, int M, std::vector<int> U, std::vector<int> V, std::vector<int> original_labels); std::variant<bool, std::vector<int>> find_journey(int N, int M, std::vector<int> U, std::vector<int> V) { std::vector<std::vector<int>> canoesfrom(N); for (int i = 0; i < M; ++i) canoesfrom[U[i]].push_back(i); std::vector<bool> seen(N); std::vector<int> stack = {0}; while (!stack.empty()) { int node = stack.back(); stack.pop_back(); if (seen[node]) continue; seen[node] = true; for (int i : canoesfrom[node]) { stack.push_back(V[i]); } } std::vector<int> newu, newv, original_labels; int newm = 0; for (int i = 0; i < N; ++i) { if (!seen[i]) continue; for (int out : canoesfrom[i]) { newu.push_back(U[out]); newv.push_back(V[out]); original_labels.push_back(out); ++newm; } } return find_journey_connected(N, newm, newu, newv, original_labels); } std::variant<bool, std::vector<int>> find_journey_connected(int N, int M, std::vector<int> U, std::vector<int> V, std::vector<int> original_labels) { std::vector<std::vector<int>> out(N); for (int i = 0; i < M; ++i) out[U[i]].push_back(i); U.push_back(-1); V.push_back(0); // dummy edge to source // stage 1: find any loop std::vector<int> is_marked(N); std::vector<int> seen(N); std::vector<int> inpath(N); std::vector<int> path; std::vector<int> stack = {M}; bool foundcyclestagei = false; while (!stack.empty()) { int canoe = stack.back(); stack.pop_back(); if (canoe == -1) { inpath[V[path.back()]] = false; path.pop_back(); continue; } path.push_back(canoe); int node = V[canoe]; if (seen[node]) { if (!inpath[node]) continue; foundcyclestagei = true; is_marked[node] = true; while (U[path.back()] != node) { is_marked[U[path.back()]] = true; path.pop_back(); } path.pop_back(); break; } seen[node] = true; inpath[node] = true; for (int to : out[node]) { stack.push_back(-1); stack.push_back(to); } } if (!foundcyclestagei) return false; // Stage 2: check multiple reachability to marked nodes std::vector<int> memo(N, -1); auto check = [&](int node, auto check) -> bool { if (memo[node] != -1) return memo[node]; if (is_marked[node]) return true; bool ok = false; for (int to : out[node]) { ok |= check(V[to], check); } return memo[node] = ok; }; bool multiplereachabilitystageii = false; for (int i = 0; i < N; ++i) { if (is_marked[i] && i != V[path.back()]) continue; int canoecnt = 0; for (int to : out[i]) { canoecnt += check(V[to], check); } multiplereachabilitystageii |= (canoecnt >= 2); } if (multiplereachabilitystageii) return true; // Stage 3: we don't have multiple reachability, but let's look for a second cycle bool foundcyclestageiii = false; stack = {M}; seen = std::vector<int>(N, false); while (!stack.empty()) { int canoe = stack.back(); stack.pop_back(); int node = V[canoe]; if (is_marked[node] && node != path.back()) continue; // avoid refinding the same cycle if (seen[node]) { foundcyclestageiii = true; break; } seen[node] = true; for (int to : out[node]) { stack.push_back(to); } } return foundcyclestageiii; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...