Submission #627258

#TimeUsernameProblemLanguageResultExecution timeMemory
627258model_code수천개의 섬 (IOI22_islands)C++17
100 / 100
425 ms44136 KiB
// correct/solution-ayaze-full.cpp #include "islands.h" #include <bits/stdc++.h> using namespace std; vector<set<pair<int, int>>> adj_list, rev_adj_list; queue<int> unprocessed_zero_outdeg; void RemoveNode(int v) { for (auto [u, edge_idx] : adj_list[v]) { rev_adj_list[u].erase({v, edge_idx}); } for (auto [u, edge_idx] : rev_adj_list[v]) { adj_list[u].erase({v, edge_idx}); if (adj_list[u].empty()) { unprocessed_zero_outdeg.push(u); } } adj_list[v].clear(); rev_adj_list[v].clear(); } // nodes, edge idxs // last node is the first cyclic node pair<vector<int>, vector<int>> FindCycle(int u, bool take_second) { auto it = adj_list[u].begin(); if (take_second) ++it; set<int> seen = {u}; vector<int> nodes = {u}; vector<int> edge_idxs = {}; auto [v, edge_idx] = *it; while (!seen.count(v)) { nodes.push_back(v); edge_idxs.push_back(edge_idx); seen.insert(v); edge_idx = adj_list[v].begin()->second; v = adj_list[v].begin()->first; } nodes.push_back(v); edge_idxs.push_back(edge_idx); return {nodes, edge_idxs}; } pair<vector<int>, vector<int>> ConstructSimpleCycle(vector<int> nodes, vector<int> edge_idxs) { int first_occ = -1; for (int i = 0 ; i+1 < static_cast<int>(nodes.size()) ; i++) { if (nodes[i] == nodes.back()) { first_occ = i; break; } } vector<int> first_path; for (int i = 0 ; i < static_cast<int>(edge_idxs.size()) ; i++) { first_path.push_back(edge_idxs[i]); } for (int i = first_occ-1 ; i >= 0 ; i--) { first_path.push_back(edge_idxs[i]); } vector<int> second_path; for (int i = 0 ; i < first_occ ; i++) { second_path.push_back(edge_idxs[i]); } for (int i = static_cast<int>(edge_idxs.size())-1 ; i >= 0 ; i--) { second_path.push_back(edge_idxs[i]); } return {first_path, second_path}; } void FindTour(int u, vector<int> &ans) { while (!unprocessed_zero_outdeg.empty()) { int v = unprocessed_zero_outdeg.front(); unprocessed_zero_outdeg.pop(); RemoveNode(v); } if (adj_list[u].empty()) { ans.push_back(-1); return; } if (static_cast<int>(adj_list[u].size()) == 1) { auto [v, edge_idx] = *adj_list[u].begin(); ans.push_back(edge_idx); RemoveNode(u); FindTour(v, ans); ans.push_back(edge_idx); return; } auto [first_cycle, first_cycle_edges] = FindCycle(u, false); auto [second_cycle, second_cycle_edges] = FindCycle(u, true); map<int, int> first_occ; for (int i = 0 ; i+1 < static_cast<int>(first_cycle.size()) ; i++) { first_occ[first_cycle[i]] = i; } int common_node = -1; int first_common_occ = -1; int second_common_occ = -1; for (int i = 1 ; i+1 < static_cast<int>(second_cycle.size()) ; i++) { if (first_occ.count(second_cycle[i])) { common_node = second_cycle[i]; second_common_occ = i; first_common_occ = first_occ[common_node]; break; } } if (common_node == -1) { // two disjoint cycles auto cycle1 = ConstructSimpleCycle(first_cycle, first_cycle_edges); auto cycle2 = ConstructSimpleCycle(second_cycle, second_cycle_edges); ans.insert(ans.end(), cycle1.first.begin(), cycle1.first.end()); ans.insert(ans.end(), cycle2.first.begin(), cycle2.first.end()); ans.insert(ans.end(), cycle1.second.begin(), cycle1.second.end()); ans.insert(ans.end(), cycle2.second.begin(), cycle2.second.end()); return; } int first_cyclic_occ = -1; for (int i = 0 ; i+1 < static_cast<int>(first_cycle.size()) ; i++) { if (first_cycle[i] == first_cycle.back()) { first_cyclic_occ = i; break; } } // loop the first path for (int i = 0 ; i < static_cast<int>(first_cycle_edges.size()) ; i++) { ans.push_back(first_cycle_edges[i]); } for (int i = first_cyclic_occ-1 ; i >= 0 ; i--) { ans.push_back(first_cycle_edges[i]); } // enter first path through second path for (int i = 0 ; i < second_common_occ ; i++) { ans.push_back(second_cycle_edges[i]); } // only one of the following loops will be executed; we want // to reach the start of the cycle for (int i = first_common_occ-1 ; i >= first_cyclic_occ ; i--) { ans.push_back(first_cycle_edges[i]); } for (int i = first_common_occ ; i < first_cyclic_occ ; i++) { ans.push_back(first_cycle_edges[i]); } // go back through the latter part of first path and second path for (int i = static_cast<int>(first_cycle_edges.size())-1 ; i >= first_common_occ ; i--) { ans.push_back(first_cycle_edges[i]); } for (int i = second_common_occ-1 ; i >= 0 ; i--) { ans.push_back(second_cycle_edges[i]); } } std::variant<bool, std::vector<int>> find_journey( int N, int M, std::vector<int> U, std::vector<int> V) { adj_list.resize(N); rev_adj_list.resize(N); for (int i = 0 ; i < M ; i++) { adj_list[U[i]].insert({V[i], i}); rev_adj_list[V[i]].insert({U[i], i}); } for (int i = 0 ; i < N ; i++) { if (adj_list[i].empty()) { unprocessed_zero_outdeg.push(i); } } vector<int> ret; FindTour(0, ret); for (int e : ret) { if (e == -1) { return false; } } return ret; }
#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...