제출 #1271072

#제출 시각아이디문제언어결과실행 시간메모리
1271072teste경주 (Race) (IOI11_race)C++20
100 / 100
548 ms39056 KiB
#include <bits/stdc++.h> using namespace std; const int INF = 1e9; int N, K; vector<vector<pair<int,int>>> adj; // (vizinho, peso) vector<int> sz; vector<char> removed; int ans = INF; int calc_sz(int v, int p){ sz[v] = 1; for(auto &e : adj[v]){ int u = e.first; if(u == p || removed[u]) continue; sz[v] += calc_sz(u, v); } return sz[v]; } int find_centroid(int v, int p, int n){ for(auto &e : adj[v]){ int u = e.first; if(u == p || removed[u]) continue; if(sz[u] > n/2) return find_centroid(u, v, n); } return v; } // coleta (peso_total, dist_em_arestas) de todos os nós na subárvore de v, // começando com dist = startDist, weight = startW void collect_paths(int v, int p, int dist, int weight, vector<pair<int,int>> &out){ if(weight > K) return; // otimização: não precisamos de pesos > K out.emplace_back(weight, dist); for(auto &e : adj[v]){ int u = e.first, w = e.second; if(u == p || removed[u]) continue; collect_paths(u, v, dist+1, weight + w, out); } } void decompose(int entry){ int n = calc_sz(entry, -1); int centroid = find_centroid(entry, -1, n); // mark centroid removed[centroid] = 1; // best: mapa peso -> menor distancia para caminhos já processados (vindo de filhos anteriores) unordered_map<int,int> best; best.reserve(64); best[0] = 0; // ficar no centróide: peso 0, dist 0 for(auto &e : adj[centroid]){ int u = e.first, w = e.second; if(removed[u]) continue; vector<pair<int,int>> paths; collect_paths(u, centroid, 1, w, paths); // primeiro, para cada caminho deste filho, tenta combinar com best (filhos anteriores) for(auto &p : paths){ int pw = p.first; int pd = p.second; int need = K - pw; auto it = best.find(need); if(it != best.end()){ ans = min(ans, pd + it->second); } } // depois atualiza best com os caminhos deste filho for(auto &p : paths){ int pw = p.first; int pd = p.second; auto it = best.find(pw); if(it == best.end() || pd < it->second) best[pw] = pd; } } // recursão nos componentes resultantes for(auto &e : adj[centroid]){ int u = e.first; if(!removed[u]) decompose(u); } // opcional: removed[centroid] = 0; // se quisermos reutilizar (mas não é necessário) } int best_path(int NN, int KK, int H[][2], int L[]){ N = NN; K = KK; adj.assign(N, {}); for(int i=0;i<N-1;i++){ int u = H[i][0], v = H[i][1], w = L[i]; adj[u].push_back({v,w}); adj[v].push_back({u,w}); } sz.assign(N,0); removed.assign(N,0); ans = INF; decompose(0); if(ans == INF) 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...