Submission #1179485

#TimeUsernameProblemLanguageResultExecution timeMemory
1179485ema_nicoleRace (IOI11_race)C++17
0 / 100
0 ms320 KiB
#pragma GCC optimize ("Ofast", "unroll-loops") #include <iostream> #include <vector> #include <unordered_map> #include <map> using namespace std; const int NMAX = 200002; using ll = long long; const int INF = 21e8; struct muchii { int nod, dist; }; vector <vector <muchii>> v; int n, k; bool f[NMAX]; ///dc deja am procesat ca centroid respectivul sau nu int parent[NMAX]; int weight[NMAX]; ///ce weight are subarb resp void dfssize(int start) { weight[start] = 0; for(auto x : v[start]) { if(x.nod == parent[start] || f[x.nod]) continue; parent[x.nod] = start; dfssize(x.nod); weight[start] += weight[x.nod]; } weight[start]++; } int centroid = -1; void dfscentroid(int start, int sizee, int tot) { ///sizeul e de sus bool ok = 0; if(sizee > tot / 2) ok = 1; for(auto x : v[start]) { if(x.nod == parent[start] || f[x.nod]) continue; if(weight[x.nod] > tot / 2) ok = 1; } if(!ok) { ///am gasit centroidul centroid = start; return; } for(auto x : v[start]) { if(x.nod == parent[start] || f[x.nod]) continue; dfscentroid(x.nod, sizee + weight[start] - weight[x.nod], tot); } } unordered_map <ll, int> umap, full; ///full pt centroid, umap pt fiul curent int ans = INF; ///dist minima pt suma k void updateans(int copil, int add) { ///start e copilul, actually if(full.find(k) != full.end()) ///dc deja e lant pana in el ans = min(ans, full[k]); for(auto var : umap) { ///ce val am pastrat in copil if(ans < INF && var.second + 1 > ans) continue; ///COMPARAM cu ce avem de la vechii fii if(full.find(k - var.first - add) != full.end()) ans = min(ans, full[k - var.first - add] + var.second + 1); } for(auto var : umap) { ///UPDATAM if(var.first + add > k || (ans < INF && var.second + 1 > ans)) continue; if(full.find(var.first + add) != full.end()) full[var.first + add] = min(full[var.first + add], var.second + 1); else full[var.first + add] = var.second + 1; } } void dfsans(int start, int add, int muchii) { ///formam dist de la noduri la centroid muchii++; if(ans < INF && muchii > ans) ///deja e drum prea lung return; for(auto x : v[start]) { if(x.nod == parent[start] || f[x.nod]) continue; if(umap.find(add + x.dist) != umap.end()) umap[add + x.dist] = min(umap[add + x.dist], muchii); else umap[add + x.dist] = muchii; dfsans(x.nod, add + x.dist, muchii + 1); } } void build(int start) { ///de la subarborele lui start INCEPEM parent[start] = -1; dfssize(start); centroid = -1; dfscentroid(start, 0, weight[start]); //cout << weight[start] << " "; parent[centroid] = -1; ///rebuild in subarborele nostru sizeurile de parinti etc dfssize(centroid); ///reindexam parintii basically full.clear(); for(auto x : v[centroid]) { if(f[x.nod]) continue; umap.clear(); umap[0] = 0; ///init-ish dfsans(x.nod, 0, 0); ///formezi drumurile updateans(x.nod, x.dist); ///unim fiul si si comparam } //cout << start << " " << centroid << " " << ans << '\n'; /*if(centroid == 39) { cout << "yoo\n"; for(int i = 0; i < n; i++) cout << i << " " << f[i] << '\n'; cout << '\n'; }*/ f[centroid] = 1; for(auto x : v[centroid]) { ///facem si in subarbori if(!f[x.nod]) build(x.nod); } } int best_path(int N, int K, int h[NMAX][2], int l[NMAX]) { n = N, k = K; v.resize(n + 1); for(int i = 0; i < n - 1; i++) { v[h[i][0]].push_back({h[i][1], l[i]}); v[h[i][1]].push_back({h[i][0], l[i]}); } /*for(int i = 0; i < n; i++) { cout << "nodul " << i << '\n'; for(auto x : v[i]) cout << x.nod << " "; cout << '\n'; }*/ build(0); if(ans == INF) ans = -1; return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...