Submission #1108206

#TimeUsernameProblemLanguageResultExecution timeMemory
1108206eymRace (IOI11_race)C++17
0 / 100
2 ms2404 KiB
#include "race.h" #include <sys/resource.h> #include <cassert> #include <cstdint> #include <functional> #include <iostream> #include <unordered_map> #include <vector> using namespace std; using i6 = int64_t; struct Edge { int len; int dst; }; vector<vector<Edge>> g; int res = INT32_MAX; int n; int k; vector<uint8_t> used; int find_centroid(int root, int total_size) { // cout << total_size << " vertices to process" << endl; vector<int> sizes(n, 1); function<int(int, int)> find_sizes = [&](int p, int u) -> int { for (auto e : g[u]) { if (e.dst == p || used[e.dst]) continue; sizes[u] += find_sizes(u, e.dst); } return sizes[u]; }; find_sizes(-1, root); function<int(int, int)> find_centroid_impl = [&](int p, int u) { for (auto e : g[u]) { if (e.dst == p || used[e.dst]) continue; if (sizes[e.dst] > total_size / 2) { return find_centroid_impl(u, e.dst); } } return u; }; return find_centroid_impl(-1, root); } void compute_solution(int root, int total_size) { if (used[root]) return; int centroid = find_centroid(root, total_size); used[centroid] = 1; unordered_map<int, int> comp_sizes; { unordered_map<i6, int> min_depth_by_dist; unordered_map<i6, int> new_min_depth_by_dist; int comp_size = 0; function<void(int, int, int, i6)> walk = [&](int parent, int u, int depth, i6 dist) { comp_size++; if (dist <= k && depth < res) { // heuristic auto it = new_min_depth_by_dist.find(dist); if (it == new_min_depth_by_dist.end()) { new_min_depth_by_dist[dist] = depth; } else { new_min_depth_by_dist[dist] = min(it->second, depth); } } for (auto e : g[u]) { if (e.dst == parent || used[e.dst]) continue; walk(u, e.dst, depth + 1, dist + e.len); } }; for (auto e : g[centroid]) { if (used[e.dst]) continue; comp_size = 0; walk(centroid, e.dst, 1, e.len); comp_sizes[e.dst] = comp_size; for (auto& [dist, depth] : new_min_depth_by_dist) { if (depth >= res) // heuristic continue; i6 rem_dist = k - dist; if (rem_dist == 0) { assert(depth > 0); res = min(res, depth); } else if (rem_dist > 0) { auto it = min_depth_by_dist.find(rem_dist); if (it != min_depth_by_dist.end()) { assert(depth + it->second > 0); res = min(res, depth + it->second); } } } for (auto& [dist, depth] : new_min_depth_by_dist) { auto it = min_depth_by_dist.find(dist); if (it == min_depth_by_dist.end()) { min_depth_by_dist[dist] = depth; } else { min_depth_by_dist[dist] = min(it->second, depth); } } new_min_depth_by_dist.clear(); } } for (auto e : g[centroid]) { compute_solution(e.dst, comp_sizes[e.dst]); } } int best_path(int N, int K, int H[][2], int L[]) { n = N; k = K; used.resize(N); g.resize(n); for (int i = 0; i < N; i++) { g[H[i][0]].push_back({L[i], H[i][1]}); g[H[i][1]].push_back({L[i], H[i][0]}); } compute_solution(0, n); return res == INT32_MAX ? -1 : res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...