제출 #367794

#제출 시각아이디문제언어결과실행 시간메모리
367794KoD즐거운 행로 (APIO20_fun)C++17
0 / 100
1 ms364 KiB
#include "fun.h" #include <vector> #include <algorithm> template <class T> using Vec = std::vector<T>; Vec<int> createFunTour(int N, int Q) { // Step 1. find centroid (N-1 queries) int centroid = 0; Vec<int> subtree(N); subtree[0] = N; for (int i = 1; i < N; ++i) { subtree[i] = attractionsBehind(0, i); if (subtree[i] * 2 >= N && subtree[i] < subtree[centroid]) { centroid = i; } } // Step 2. compute distances from the centroid (N-1 queries) Vec<int> dist(N); for (int i = 0; i < N; ++i) { if (i != centroid) { dist[i] = hoursRequired(centroid, i); } } // Step 3. find direct children of the centroid (0 queries) Vec<int> children; Vec<int> group_size; for (int i = 0; i < N; ++i) { if (dist[i] == 1) { children.push_back(i); group_size.push_back(subtree[i] < subtree[centroid] ? subtree[i] : N - subtree[centroid]); } } // Step 4. classify vertices (at most 2N-2 queries) Vec<int> belong(N, (int) children.size() - 1); for (int i = 0; i < (int) children.size() - 1; ++i) { const auto root = children[i]; for (int u = 0; u < N; ++u) { if (u != centroid && attractionsBehind(u, root) > group_size[i]) { belong[u] = i; } } } // Step 5. construct a fun tour (0 queries) Vec<int> ret; ret.reserve(N); Vec<Vec<int>> vertices(children.size()); for (int i = 0; i < N; ++i) { if (i != centroid) { vertices[belong[i]].push_back(i); } } for (auto &vec: vertices) { std::sort(vec.begin(), vec.end(), [&](const int i, const int j) { return dist[i] < dist[j]; }); } const auto farthest = [&](const int i) { return vertices[i].empty() ? -1 : dist[vertices[i].back()]; }; int pivot = -1, last = -1; while (true) { int sum = 0; for (int i = 0; i < (int) children.size(); ++i) { sum += (int) vertices[i].size(); } for (int i = 0; i < (int) children.size(); ++i) { if (2 * ((int) vertices.size()) == sum + 1) { pivot = i; } } if (pivot != -1) { break; } int select = -1, score = -1; for (int i = 0; i < (int) children.size(); ++i) { if (i != last) { const auto tmp = farthest(i); if (score < tmp) { select = i; score = tmp; } } } ret.push_back(vertices[select].back()); vertices[select].pop_back(); last = select; } while (true) { ret.push_back(vertices[pivot].back()); vertices[pivot].pop_back(); int select = -1, score = -1; for (int i = 0; i < (int) children.size(); ++i) { if (i != pivot) { const auto tmp = farthest(i); if (score < tmp) { select = i; score = tmp; } } } if (select == -1) { break; } ret.push_back(vertices[select].back()); vertices[select].pop_back(); } ret.push_back(centroid); 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...