Submission #745582

#TimeUsernameProblemLanguageResultExecution timeMemory
745582shoryu386Race (IOI11_race)C++17
21 / 100
173 ms54576 KiB
#include <bits/stdc++.h> using namespace std; //#include "race.h" #define int long long int n,k; #define MAXN 200007 unordered_map<int, int> al[MAXN]; int ans = 2*MAXN; unordered_map<int, int> merger[MAXN]; int offset[MAXN] = {0}; int valoffset[MAXN] = {0}; int dfs(int node, int p){ int largest = -1, largestVal = -1; int totalSize = 1; for (auto x : al[node]){ if (x.first == p) continue; int ss = dfs(x.first, node); totalSize += ss; if (ss > largestVal){ largestVal = ss; largest = x.first; } } //we need to merge while checking :D if (largest != -1){ swap(merger[node], merger[largest]); offset[node] = offset[largest] + al[node][largest]; valoffset[node] = valoffset[largest] + 1; merger[node][-offset[node]] = -valoffset[node]; if (merger[node].count(k - offset[node]) != 0){ int torture = merger[node][k - offset[node]]; ans = min(ans, torture + valoffset[node]); } for (auto x : al[node]){ if (x.first == p || x.first == largest) continue; for (auto y : merger[x.first]){ //check if x.second + y.first - offset[x.first] can form k with a value from (merger[node]) but offset by offset[node] //check if k - (x.second + y.first - offset[x.first] - offset[node]) can be found int trueValSec = y.first + offset[x.first] + al[node][x.first]; //cerr << node << ' ' << x.first << ' ' << trueValSec << ' ' << k - trueValSec + offset[node] << '\n'; /* cout << "For node " << node << '\n'; for (auto x : merger[node]){ if (x.first + offset[node] == k){ //ans = min(ans, x.second + valoffset[node]); } cout << x.first + offset[node] << ' ' << x.second + valoffset[node] << '\n'; } * */ //we want k = trueval + trueValSec //k - truevalSec = trueVal //k - trueValSec = valFound - offset //k - trueValSec + offset[node] = valFound //valFound = trueval + offset[] //if (node == 0 && x.first == 1) cout << trueValSec << ' ' << k - trueValSec - offset[node] << "\n\n\n"; if (merger[node].count(k - trueValSec - offset[node]) != 0){ int torture = merger[node][k - trueValSec - offset[node]] + valoffset[x.first]; ans = min(ans, torture + y.second + valoffset[node] + 1); } } for (auto y : merger[x.first]){ int intendedAdd = y.first + offset[x.first] - offset[node] + x.second; if (merger[node].count(intendedAdd) == 0 || merger[node][intendedAdd] > y.second + 1 - valoffset[x.first] - valoffset[node]){ merger[node][intendedAdd] = y.second + 1 + valoffset[x.first] - valoffset[node]; } } } } merger[node][-offset[node]] = -valoffset[node]; //cout << "For node " << node << '\n'; if (merger[node].count(k - offset[node]) != 0){ ans = min(ans, merger[node][k - offset[node]] + valoffset[node]); } /* for (auto x : merger[node]){ if (x.first + offset[node] == k){ ans = min(ans, x.second + valoffset[node]); } //cout << x.first + offset[node] << ' ' << x.second + valoffset[node] << '\n'; } */ return totalSize; } mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count()); int randint(int a, int b) { return uniform_int_distribution<int>(a, b)(mt_rng); } int32_t best_path(int32_t N, int32_t K, int32_t H[][2], int32_t L[]){ n = N; k = K; for (int x = 0; x < n-1; x++){ int a, b; a = H[x][0], b = H[x][1]; al[a][b] = L[x]; al[b][a] = L[x]; } dfs(randint(0, n-1), -1); if (ans > MAXN) return -1; return ans; } /* main(){ int32_t H[][2] = {{0,1},{1,2},{1,3}, {0,4},{4,5},{4,6}}; int32_t L[] = {4,3,2,50,7,9}; cout << best_path(7, 56, H, L); } */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...