Submission #348637

#TimeUsernameProblemLanguageResultExecution timeMemory
348637milleniumEeee통행료 (IOI18_highway)C++17
51 / 100
392 ms262144 KiB
#include "highway.h" //#include "grader.cpp" #include <bits/stdc++.h> #define pii pair<int, int> #define fr first #define sc second #define szof(s) (int)s.size() #define all(s) s.begin(), s.end() #define mk make_pair #define pb push_back #define ll long long using namespace std; const int MAXN = 130005; const int INF = 0x3f3f3f3f; ll from[MAXN], to[MAXN]; vector <ll> g[MAXN]; ll dist[MAXN]; ll pr[MAXN]; ll costa, costb; ll min_path; ll diametr; ll n, m; ll Q; map <pii, ll> id; void make_edge(ll x, ll y) { g[x].pb(y); g[y].pb(x); } ll find_middle_edge() { ll l = 0, r = m - 1; vector <int> w(m); while (l != r) { ll mid = (l + r) >> 1; for (ll i = l; i <= r; i++) { if (i <= mid) { w[i] = 1; } else { w[i] = 0; } } ll cur_cost = ask(w); Q++; if (cur_cost != min_path) { r = mid; } else { l = mid + 1; } } return l; } ll get_min_path() { vector <int> w(m); for (int i = 0; i < m; i++) { w[i] = 0; } ll cur_cost = ask(w); Q++; return cur_cost; } void dfs(ll v, ll par, ll len, vector <ll> &s_sub) { for (int to : g[v]) { if (to != par) { s_sub.pb(id[{v, to}]); dfs(to, v, len + 1, s_sub); } } } void calc_dist_and_pr(int v, int par, int len) { dist[v] = len; pr[v] = par; for (int to : g[v]) { if (to != par) { calc_dist_and_pr(to, v, len + 1); } } } int find_s(vector <ll> s_sub) { vector <int> w(m, 0); for (ll el : s_sub) { w[el] = 1; } ll cost = ask(w); Q++; ll root_to_s = (cost - min_path) / (costb - costa); vector <int> possible; for (int i = 0; i < n; i++) { if (dist[i] == root_to_s) { possible.pb(id[{i, pr[i]}]); } } ll l = 0, r = szof(possible) - 1; while (l != r) { ll mid = (l + r) >> 1; for (ll i = 0; i < m; i++) { w[i] = 0; } for (ll i = l; i <= mid; i++) { w[possible[i]] = 1; } ll cur_cost = ask(w); Q++; if (cur_cost != min_path) { r = mid; } else { l = mid + 1; } } ll need_edge = possible[l]; if (dist[from[need_edge]] == root_to_s) { return from[need_edge]; } else { return to[need_edge]; } } void find_pair(int N, vector<int> U, vector<int> V, int AA, int BB) { costa = AA, costb = BB; m = U.size(); n = N; for (ll i = 0; i < m; i++) { from[i] = U[i]; to[i] = V[i]; id[{from[i], to[i]}] = i; id[{to[i], from[i]}] = i; make_edge(from[i], to[i]); } min_path = get_min_path(); diametr = min_path / costa; ll mid_edge = find_middle_edge(); ll root = from[mid_edge]; ll need_sub = to[mid_edge]; vector <ll> s_sub; s_sub.pb(id[{root, need_sub}]); memset(dist, -1, sizeof(dist)); calc_dist_and_pr(need_sub, root, 1); dist[root] = 0; dfs(need_sub, root, 1, s_sub); ll SS = find_s(s_sub); memset(dist, -1, sizeof(dist)); calc_dist_and_pr(SS, -1, 0); vector <ll> possible; for (ll i = 0; i < n; i++) { if (dist[i] == diametr) { possible.pb(id[{i, pr[i]}]); } } ll l = 0, r = szof(possible) - 1; vector <int> w(m); while (l != r) { ll mid = (l + r) >> 1; for (ll i = 0; i < m; i++) { w[i] = 0; } for (ll i = l; i <= mid; i++) { w[possible[i]] = 1; } ll cur_cost = ask(w); Q++; if (cur_cost != min_path) { r = mid; } else { l = mid + 1; } } ll need_edge = possible[l]; ll TT; if (dist[from[need_edge]] == diametr) { TT = from[need_edge]; } else { TT = to[need_edge]; } if (SS > TT) { swap(SS, TT); } answer(SS, TT); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...