제출 #269792

#제출 시각아이디문제언어결과실행 시간메모리
269792shivensinha4경주 (Race) (IOI11_race)C++17
21 / 100
3077 ms163324 KiB
#include <bits/stdc++.h> //#include "race.h" using namespace std; #define for_(i, s, e) for (int i = s; i < e; i++) #define for__(i, s, e) for (ll i = s; i < e; i++) #define SSTR(x) static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str() typedef long long ll; typedef vector<int> vi; typedef pair<int, int> ii; //#define endl '\n' int n, k, l, timer = 0; vector<vector<pair<int, ll>>> adjList; vi removed, subtreeSize, centroid, tin, tout; vector<unordered_map<ll, vector<ii>>> paths; // {length, {child, roads}} vector<vi> up; vector<vector<ll>> upDist; int ans = 1e9; int dfs(int p, int parent) { int s = 1; tin[p] = ++timer; for_(i, 1, l+1) { up[p][i] = up[up[p][i-1]][i-1]; upDist[p][i] = upDist[p][i-1] + upDist[up[p][i-1]][i-1]; } for (auto i: adjList[p]) if (i.first != parent) { up[i.first][0] = p; upDist[i.first][0] = i.second; s += dfs(i.first, p); } subtreeSize[p] = s; tout[p] = ++timer; return s; } bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; } int lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], v)) u = up[u][i]; return up[u][0]; } // {distance, edges} pair<ll, int> ancDist(int u, int anc) { if (u == anc) return {0, 0}; ll dist = 0, edges = 0; for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], anc)) { dist += upDist[u][i]; edges += (1 << i); u = up[u][i]; } return {dist + upDist[u][0], edges+1}; } pair<ll, int> dist(int u, int v) { int lc = lca(u, v); ii a = ancDist(u, lc), b = ancDist(v, lc); return {a.first + b.first, a.second + b.second}; } void decompose(int p, int c) { int invalidChild = -1, sizeLimit = (subtreeSize[p] >> 1); for (auto i: adjList[p]) if (!removed[i.first] and subtreeSize[i.first] > sizeLimit) { invalidChild = i.first; break; } if (invalidChild != -1) { subtreeSize[p] -= subtreeSize[invalidChild]; subtreeSize[invalidChild] += subtreeSize[p]; return decompose(invalidChild, c); } removed[p] = true; centroid[p] = c; for (auto i: adjList[p]) if (!removed[i.first]) { centroid[i.first] = p; decompose(i.first, p); } } void updateParents(int p) { int a = p, b = centroid[p]; while (b != -1) { ii d = dist(p, b); paths[b][d.first].push_back({d.second, a}); a = b; b = centroid[b]; } } void solve(int p) { int a = p, b = centroid[p]; while (b != -1) { ii d = dist(p, b); for (auto o: paths[b][k-d.first]) if (o.second != a) { ans = min(ans, o.first + d.second); break; } a = b; b = centroid[b]; } } int best_path(int N, int K, int H[][2], int L[]) { n = N, k = K; adjList.resize(n); subtreeSize.resize(n); removed.resize(n); paths.resize(n); centroid.resize(n, -1); tin.resize(n); tout.resize(n); up.resize(n); l = ceil(log2(n)); up.assign(n, vi(l+1)); upDist.assign(n, vector<ll>(l+1)); for_(i, 0, n-1) { int a, b; ll w; a = H[i][0], b = H[i][1]; w = L[i]; adjList[a].push_back({b, w}); adjList[b].push_back({a, w}); } dfs(0, 0); decompose(0, -1); for_(i, 0, n) updateParents(i); for_(i, 0, n) { paths[i][0].push_back({0, -1}); for (auto o: paths[i]) if (o.second.size() > 1) { sort(paths[i][o.first].begin(), paths[i][o.first].begin()+2); } } for_(i, 0, n) solve(i); return (ans == 1e9 ? -1 : ans); } //int main() { //#ifndef ONLINE_JUDGE //freopen("test.in", "r", stdin); //#endif //ios_base::sync_with_stdio(false); //cin.tie(0); //int H[100000][2], L[100000]; //int N, K; //cin >> N >> K; //for_(i, 0, N-1) { //int a, b; ll w; cin >> a >> b >> w; //H[i][0] = a; H[i][1] = b; //L[i] = w; //} //cout << best_path(N, K, H, L) << endl; //return 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...