Submission #159721

#TimeUsernameProblemLanguageResultExecution timeMemory
159721rama_pangDreaming (IOI13_dreaming)C++14
14 / 100
81 ms16248 KiB
#include "dreaming.h" #include <bits/stdc++.h> using namespace std; /* Find the diameters (d) of all connected components. Let's denote the distance from optimal connection point such thay distance from this node to all other nodes are minimized as the radius. The radius then must lie on the diameter. Sort all connected components in descending order, r1 >= r2 >= r3 >=... There are two cases: - If r1 + r2 + L <= d1 Then if we connect all components on r1, then the diameter won't ever change. In this case, the answer is d1. - If r1 + r2 + L > d1 Let's join these two trees, and find it's radius. It's obvious that the radius lies on the path r1-L-r2, with radius rn. We must minimize rn, and since r1 >= r2, then the optimal rn is in tree1, since if it is at tree2, them L + r1 > r2, is an order of magnitude greater than minimal possible, that is, r1 < L + r2. Thus the optimal rn is on the path of r1. However, since r1 + r2 + L > d1 and d1 <= 2 * r1, r2 + L > r1. Thus we must minimize the distance to r2, that is, at the position of r1. We can just connect all components to the node containing r1. The answer is then the maximum of r1 + r2 + L and r2 + r3 + 2 * L, all other radius will yield less. */ int dfs(int n, int now, int p, vector<int> &dist, const vector<vector<pair<int, int>>> &G) { dist[n] = now; int id = n, mx = 0; for (auto i : G[n]) if (i.second != p) { int k = dfs(i.second, now + i.first, n, dist, G); if (dist[k] > mx) { mx = dist[k]; id = k; } } return id; } bool get_diameter(int n, int t, int p, vector<int> &d, const vector<vector<pair<int, int>>> &G) { if (n == t) { d.push_back(t); return true; } for (auto i : G[n]) if (i.second != p) { if (get_diameter(i.second, t, n, d, G)) { d.push_back(n); return true; } } return false; } void dfs_clear(int n, vector<int> &vis, vector<int> &dist, const vector<vector<pair<int, int>>> &G) { if (vis[n] == 1) return; dist[n] = 0; vis[n] = 1; for (auto i : G[n]) dfs_clear(i.second, vis, dist, G); } int get_radius(int n, int &max_d, const vector<vector<pair<int, int>>> &G, vector<int> &vis, vector<int> &dist) { if (vis[n]) return -1; int N = G.size(); /* two dfs to determine diameter of current connected tree */ int u = dfs(n, 0, -1, dist, G); int v = dfs(u, 0, -1, dist, G); vector<int> diameter; get_diameter(u, v, -1, diameter, G); reverse(diameter.begin(), diameter.end()); /* u is first element in diameter, v is furthest element */ int minim = INT_MAX; for (auto i : diameter) minim = min(minim, max(dist[i], dist[v] - dist[i])); max_d = max(max_d, dist[v]); dfs_clear(n, vis, dist, G); return minim; } int travelTime(int N, int M, int L, int A[], int B[], int T[]) { vector<vector<pair<int, int>>> G(N); vector<int> visited(N), dist(N); for (int i = 0; i < M; i++) { G[A[i]].emplace_back(T[i], B[i]); G[B[i]].emplace_back(T[i], A[i]); } priority_queue<int, vector<int>, greater<int>> max_radius; int max_d = 0; for (int i = 0; i < M; i++) { int radius = get_radius(i, max_d, G, visited, dist); if (radius != -1) max_radius.push(radius); while (max_radius.size() > 3) max_radius.pop(); } vector<int> rad; while (!max_radius.empty()) { rad.push_back(max_radius.top()); max_radius.pop(); } sort(rad.begin(), rad.end(), greater<int>()); int res = max({max_d, rad[0] + rad[1] + L, ((rad.size() > 2)? (rad[1] + rad[2] + L + L) : 0)}); return res; }

Compilation message (stderr)

dreaming.cpp: In function 'int get_radius(int, int&, const std::vector<std::vector<std::pair<int, int> > >&, std::vector<int>&, std::vector<int>&)':
dreaming.cpp:67:9: warning: unused variable 'N' [-Wunused-variable]
     int N = G.size();
         ^
#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...