제출 #116464

#제출 시각아이디문제언어결과실행 시간메모리
116464YazanZk공장들 (JOI14_factories)C++17
15 / 100
8045 ms194180 KiB
#include <bits/stdc++.h> typedef long long ll; using namespace std; /*************** LCA ******************/ const int N = 5 * 1e5 + 1 ; const int Log = 20; const ll inf = 1e18 ; int n ; int P[Log][N], L[N] ; ll cost[N]; vector < pair < int, int > > G[N]; void dfs(int u, int p, int d, ll w) { P[0][u] = p ; L[u] = d ; cost[u] = w; for(auto e : G[u]) { int v = e.first, c = e.second ; if(v == p) continue ; dfs(v, u, d + 1, w + c); } } void dp() { for(int j = 1 ; (1 << j) < n ; j++) for(int i = 0 ; i < n ; i++) if(P[j - 1][i] != -1) P[j][i] = P[j - 1][P[j - 1][i]] ; } int lca(int u, int v) { if(L[u] < L[v]) swap(u, v); int i, log ; for(log = 1 ; (1 << log) <= L[u] ; log++); log -- ; for(i = log ; i >= 0 ; i--) { if(L[u] - (1 << i) >= L[v]) u = P[i][u] ; } if(u == v) return u ; for(i = log ; i >= 0 ; i--) { if(P[i][u] != -1 && P[i][u] != P[i][v]) u = P[i][u], v = P[i][v] ; } return P[0][u]; } inline ll dist(int &u, int &v) { return cost[u] + cost[v] - 2 * cost[lca(u, v)]; } /*************** Centroid ******************/ int sub[N], p[N] , par[N]; bool blocked[N]; void get_size(int u, int pa) { p[u] = pa ; sub[u] = 1 ; for(auto e : G[u]) { int v = e.first ; if(v == pa || blocked[v]) continue ; get_size(v, u); sub[u] += sub[v]; } } int get_centroid(int src) { get_size(src, src); int centroid = src, best = sub[src] ; queue < int > Q ; Q.emplace(src); while(!Q.empty()) { int u = Q.front(); Q.pop(); int size = sub[src] - sub[u]; for(auto e : G[u]) { int v = e.first; if(v == p[u] || blocked[v]) continue ; Q.emplace(v); size = max(size, sub[v]); } if(best > size) { best = size; centroid = u ; } } blocked[centroid] = true; for(auto e : G[centroid]) { int v = e.first ; if(blocked[v]) continue ; int child = get_centroid(v); par[child] = centroid ; } return centroid ; } ll ans[N]; int vis[N]; int t = 1 ; vector < ll > dis[N]; inline void update(int &u) { int v = u ; int i = 0 ; while(true) { if(vis[v] != t) vis[v] = t , ans[v] = inf ; ans[v] = min(ans[v], dis[u][i]); if(v == par[v]) break ; v = par[v]; i++ ; } } inline ll query(int &u) { int v = u ; ll ret = inf ; int i = 0 ; while(true) { if(vis[v] != t) vis[v] = t , ans[v] = inf ; ret = min(ret, ans[v] + dis[u][i]); if(v == par[v]) break ; v = par[v]; i++ ; } return ret; } ll Query(int S, int X[], int T, int Y[]) { t++ ; for(int i = 0 ; i < T ; i++) { update(Y[i]); } ll ret = inf ; for(int i = 0 ; i < S ; i++) { ret = min(ret, query(X[i])); } return ret; } void Init(int N, int A[], int B[], int D[]) { n = N ; for(int i = 0 ; i < n - 1 ; i++) { int u = A[i], v = B[i], w = D[i]; G[u].push_back({v, w}); G[v].push_back({u, w}); } memset(P , -1 , sizeof P); dfs(0, -1, 0, 0); dp(); int root = get_centroid(0); par[root] = root; for(int i = 0 ; i < n ; i++) { int v = i ; while(true) { dis[i].push_back(dist(v, i)); if(v == par[v]) break ; v = par[v]; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...