Submission #703541

#TimeUsernameProblemLanguageResultExecution timeMemory
703541jophyyjhRail (IOI14_rail)C++14
56 / 100
515 ms151008 KiB
/** * [S1-3] Let d(u,v) be the dist from station u to station v. * Obs1: d(.,.) is a norm. * We know dist(u,v) = dist(v,u) and dist(a,b) + dist(b,c) >= dist(a,c). This * means we can pre-compute the dist between every pair of nodes. * Obs2: For every u, d(u,v) (v != u) achieves the min => v and u are different * types of station. v is the first station we can get to after leaving u. * For simplicity, we define v to be u's "conjugate" iff d(u,v) achieves * the minimum over all v. It is easy to see that every node has a unique * conjugate. * These observations lead us to a recursive solution. Find a conjugate pair * (u,v) with no other stations between them. (A pair always exists~) d(u,v) is * their difference in block number. The pair splits the railway line into two * parts - a left and a right part. We can determine which part a station w * belongs to by finding which one of d(w,u), d(w,v) is smaller. Assign u, v to * their corresponding part and recursively solve them would be good. * * Calls needed: n * (n - 1) / 2 * Implementation 1 (Solves [S1-3] (bound tight) */ #include <bits/stdc++.h> #include "rail.h" typedef std::vector<int> vec; const int INF = 0x3f3f3f3f; std::vector<vec> dist; int* location; // location of the stations, ans variable int* s_type; // station type, ans variable inline void set_conj(int s, int t) { s_type[t] = 3 - s_type[s]; location[t] = (s_type[s] == 1 ? 1 : -1) * dist[s][t] + location[s]; } void solve(vec nodes, int ref) { if (int(nodes.size()) == 1) return; int r1 = -1, r2 = -1, min_dist = INF; for (int k : nodes) { if (k != ref && dist[k][ref] < min_dist) min_dist = dist[k][ref], r1 = k; } set_conj(ref, r1); min_dist = INF; for (int k : nodes) { if (k != r1 && dist[k][r1] < min_dist) min_dist = dist[k][r1], r2 = k; } set_conj(r1, r2); vec part1 = {r1}, part2 = {r2}; for (int k : nodes) { if (k == r1 || k == r2 || s_type[k] != 0) continue; if (dist[k][r1] <= min_dist) set_conj(r1, k); else if (dist[k][r2] <= min_dist) set_conj(r2, k); else if (dist[k][r1] < dist[k][r2]) part1.push_back(k); else part2.push_back(k); } solve(part1, r1); solve(part2, r2); } void findLocation(int n, int first, int _location[], int _s_type[]) { location = _location, s_type = _s_type; memset(s_type, 0, sizeof(int) * n); dist.assign(n, vec(n, 0)); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) dist[i][j] = dist[j][i] = getDistance(i, j); } vec all_nodes(n); for (int i = 0; i < n; i++) all_nodes[i] = i; location[0] = first, s_type[0] = 1; solve(all_nodes, 0); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...