This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |