Submission #1274256

#TimeUsernameProblemLanguageResultExecution timeMemory
1274256adembyRace (IOI11_race)C++20
0 / 100
1 ms332 KiB
//بسم الله الرحمان الرحيم //we are the winners //we are the champions #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>; #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define pb emplace_back #define lv (v<<1) #define rv ((v<<1)|1) #define endl '\n' #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; struct Centroid_Decomposition { /* Internals */ int n, k, ans; const vector<vector<pii>>& adj; vector<int> sub_sz, is_centroid, other; /* Problem Specific */ // ... /* Initialize the Centroid Decomposition */ Centroid_Decomposition(int n, int k, const vector<vector<pii>> &g) : n(n), k(k), ans(n), adj(g), sub_sz(n + 10), is_centroid(n + 10), other(k + 10) {} /* Update subtree size of each node */ int updateSize(int u, int p = -1){ sub_sz[u] = 1; for (auto [v, w] : adj[u]) if (v != p && !is_centroid[v]) sub_sz[u] += updateSize(v, u); return sub_sz[u]; } /* Get centroid of subtree rooted at u */ int getCentroid(int u, int target, int p = -1){ for(auto [v, w] : adj[u]){ if(v == p || is_centroid[v]) continue; if((sub_sz[v]>>1) > target) return getCentroid(v, target, u); } return u; } void update_ans(int u, int p, int dep_cent, int dist_cent) { if (dist_cent > k) return; int cand = other[k-dist_cent]; if (cand > 0 || k-dist_cent == 0) ans = min(ans, cand + dep_cent); for (auto& [nxt, w] : adj[u]) { if(nxt == p || is_centroid[nxt]) continue; update_ans(nxt, u, dep_cent+1, dist_cent+w); } } void update_lens(int u, int p, int dep_cent, int dist_cent) { if (dist_cent > k) return; int& cand = other[dist_cent]; if (cand > 0) cand = min(cand, dep_cent); else { cand = dep_cent; } for (auto& [nxt, w] : adj[u]) { if(nxt == p || is_centroid[nxt]) continue; update_lens(nxt, u, dep_cent+1, dist_cent+w); } } void delete_lens(int u, int p, int dep_cent, int dist_cent) { if (dist_cent > k) return; other[dist_cent] = 0; for (auto& [nxt, w] : adj[u]) { if(nxt == p || is_centroid[nxt]) continue; delete_lens(nxt, u, dep_cent+1, dist_cent+w); } } /* Decompose tree into centroid tree */ void Centroid(int u, int p){ int cur_sz = updateSize(u); int centroidPoint = getCentroid(u, cur_sz); is_centroid[centroidPoint] = true; // do something with centroid for(auto [v, w] : adj[centroidPoint]){ if(is_centroid[v]) continue; update_ans(v, centroidPoint, 1, w); update_lens(v, centroidPoint, 1, w); } for(auto [v, w] : adj[centroidPoint]){ if(is_centroid[v]) continue; delete_lens(v, centroidPoint, 1, w); } for(auto [v, w] : adj[centroidPoint]){ if(is_centroid[v]) continue; // prepare for a dive Centroid(v, centroidPoint); // recover } // do something with centroid } // Call this function to decompose the tree void Decompose(){ Centroid(0, -1); } }; int best_path(int _n, int _k, int e[][2], int w[]) { int n = _n; int k = _k; int ans = n; vector<vector<pii>> adj(n); rep(i, 0, n-1) { adj[e[i][0]].pb(e[i][1], w[i]); adj[e[i][1]].pb(e[i][0], w[i]); } Centroid_Decomposition cent(n, k, adj); cent.Decompose(); if (ans == n) return -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...