제출 #764723

#제출 시각아이디문제언어결과실행 시간메모리
764723Magikarp4000경주 (Race) (IOI11_race)C++17
21 / 100
3064 ms123268 KiB
#include "race.h" #include <bits/stdc++.h> using namespace std; #define OPTM ios_base::sync_with_stdio(0); cin.tie(0); #define INF int(1e9+7) #define ln '\n' #define ll long long #define ull unsigned long long #define ui unsigned int #define us unsigned short #define FOR(i,s,n) for (int i = s; i < n; i++) #define FORR(i,n,s) for (int i = n; i > s; i--) #define FORX(u, arr) for (auto u : arr) #define PB push_back #define in(v,x) (v.find(x) != v.end()) #define F first #define S second #define PII pair<int, int> #define PLL pair<ll, ll> #define UM unordered_map #define US unordered_set #define PQ priority_queue #define ALL(v) v.begin(), v.end() const ll LLINF = 1e18+1; #define int long long struct Edge { int F,w; }; const int MAXN = 2e5+1, LOG = 19; int n,k; US<int> v[MAXN]; vector<PII> v1[MAXN], add; int dist[MAXN], len[MAXN], p[MAXN], sz[MAXN]; UM<int,int> mp; int jump[MAXN][LOG]; int res = LLINF; void pre_dfs(int s, int pa) { FORX(u,v1[s]) { if (u.F == pa) continue; dist[u.F] = dist[s]+1; len[u.F] = len[s]+u.S; p[u.F] = s; pre_dfs(u.F,s); } } void pre_lca() { FOR(i,0,n) jump[i][0] = p[i]; FOR(j,1,LOG) { FOR(i,0,n) { jump[i][j] = jump[jump[i][j-1]][j-1]; } } } int lca(int a, int b) { if (dist[a] < dist[b]) swap(a,b); FORR(j,LOG-1,-1) { if (dist[a]-(1<<j) >= dist[b]) a = jump[a][j]; } if (a == b) return a; FORR(j,LOG-1,-1) { if (jump[a][j] != jump[b][j]) { a = jump[a][j]; b = jump[b][j]; } } return p[a]; } int find_centroid(int s, int pa, int num) { FORX(u,v[s]) { if (u == pa) continue; if (sz[u] > num/2) return find_centroid(u,s,num); } return s; } void dfs(int s, int pa) { sz[s] = 1; FORX(u,v[s]) { if (u == pa) continue; dfs(u,s); sz[s] += sz[u]; } } void dfs1(int s, int pa, int src) { FORX(u,v[s]) { if (u == pa) continue; int anc = lca(u,src); int l = len[u]+len[src]-2*len[anc]; int d = dist[u]+dist[src]-2*dist[anc]; if (l == k) res = min(res, d); else if (l < k && mp.count(k-l)) res = min(res, d+mp[k-l]); add.PB({l,d}); dfs1(u,s,src); if (s == src) { FORX(y,add) { int l = y.F, d = y.S; if (!mp.count(l)) mp[l] = d; else mp[l] = min(mp[l],d); } add.clear(); } } } void decomp(int s, int pa) { mp.clear(); dfs(s,pa); int c = find_centroid(s,pa,sz[s]); dfs1(c,-1,c); vector<int> tmp; FORX(u,v[c]) if (u != pa) tmp.PB(u); FORX(u,tmp) { v[c].erase(u); v[u].erase(c); decomp(u,c); } } int32_t best_path(int32_t N, int32_t K, int32_t H[][2], int32_t L[]) { OPTM; n = N; k = K; FOR(i,0,n-1) { v1[H[i][0]].PB({H[i][1],L[i]}); v1[H[i][1]].PB({H[i][0],L[i]}); v[H[i][0]].insert(H[i][1]); v[H[i][1]].insert(H[i][0]); } pre_dfs(0,-1); pre_lca(); decomp(0,-1); return res == LLINF ? -1 : res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...