// tem uma arvore
// cada companhia produz uma materia smp dif - cada uma tem no minimo
// uma industria, essa ficam nos vertices
// pode ter mais de uma industria numa msm cidade
// as vzs uma precisa de material da outra
// queremos minimizar a dist a ser percorrida ao precisar de uma materia da ind G
// query: a companhia u (com empresas em x1, x2,...) precisa
// de material da companhia v (com empresas em y1, y2, ...)
// qual a menor dist?
// lca + centroid
// pega de um centroid p outro
// guarda o mais prox e p subir do vertice p centroide e de um p outro
// usa o lca pra pegar a dist
// atualiza o centroid p cada empresa q lê
// vendo se ela cria um novo caminho minimo
// pega o min entre oq ja ta e o min entre o vertice ate o cara k (centroid)
// na query queremos o minimo de ir ate o centroid atual e a menor
// dist q ele tem pra algm empresa A
// lca em o(1) -> lca entre a e b é o cara na euler entre eles com menor nivel
#include "factories.h"
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5 ;
const long long inf = 1e18 ;
const int maxl = 21 ;
int n, tab[maxl][maxn], log_[maxn], kra[maxn], dp[maxl][maxn], nivel[maxn], cent[maxn] ;
long long dist[maxn], resp[maxn], pos[maxn] ;
int sz[maxn], pai[maxn], timer ;
bool vis[maxn], mark[3*maxn] ;
int tin[maxn], tout[maxn] ;
vector<pair<int,int>> grafo[maxn] ;
vector<int> euler ;
int lca(int u, int v){
int r = max(pos[v], pos[u]), l = min(pos[v], pos[u]) ;
int d = log2(r-l+1) ;
if(nivel[dp[d][l]] < nivel[dp[d][r+1-(1<<d)]]) return dp[d][l] ;
else return dp[d][r+1-(1<<d)] ;
}
long long find_dist(int a, int b){
return dist[a] + dist[b] - ((dist[lca(a, b)])<<1) ;
}
void update_cent(int u){
int k = u ;
while(k){
resp[k] = min(resp[k], find_dist(u, k)) ;
k = pai[k] ;
}
}
void ini(int u){
int k = u ;
while(k){
resp[k] = inf ; k = pai[k] ;
}
}
long long query(int x){
int k = x ; long long ans = inf ;
while(k){
if(resp[k] < ans) ans = min(ans, find_dist(x, k) + resp[k]) ;
k = pai[k] ;
}
return ans ;
}
long long Query(int S, int X[], int T, int Y[]) {
long long ans = inf ;
for(int i = 0 ; i < S ; i++) update_cent(X[i]+1) ;
for(int i = 0 ; i < T ; i++) ans = min(ans, query(Y[i]+1)) ;
for(int i = 0 ; i < S ; i++) ini(X[i]+1) ;
return ans ;
}
void dfs_cent(int v, int p){
sz[v] = 1 ;
for(auto a : grafo[v]){
if(cent[a.first] || a.first == p) continue ;
dfs_cent(a.first, v) ;
sz[v] += sz[a.first] ;
}
}
int find_cent(int v, int p, int szz){
for(auto a : grafo[v]){
if(a.first == p || cent[a.first] || (sz[a.first]<<1) <= szz) continue ;
return find_cent(a.first, v, szz) ;
}
return v ;
}
void make_cent(int v, int p){
dfs_cent(v, p) ;
int c = find_cent(v, p, sz[v]) ;
cent[c] = 1, pai[c] = p ;
for(auto a : grafo[c]){
if(cent[a.first]) continue ;
make_cent(a.first, c) ;
}
}
void dfs(int v, int p){
vis[v] = 1 ;
tab[0][v] = p ;
tin[v] = ++timer ;
pos[v] = euler.size() ;
euler.push_back(v) ;
for(auto a : grafo[v]){
if(vis[a.first] || a.first == p) continue ;
nivel[a.first] = nivel[v] + 1 ;
dist[a.first] = dist[v] + a.second ;
dfs(a.first, v) ;
euler.push_back(v) ;
}
tout[v] = ++timer ;
}
void build(){
int qtd = euler.size() ;
for(int i = 0 ; (1<<i) <= qtd ; i++){
for(int j = 1 ; j + (1<<i) <= qtd ; j++){
if(!i) dp[i][j] = euler[j] ;
else if(nivel[dp[i-1][j]] < nivel[dp[i-1][j+(1<<(i-1))]]) dp[i][j] = dp[i-1][j] ;
else dp[i][j] = dp[i-1][j+(1<<(i-1))] ;
}
}
}
void Init(int N, int A[], int B[], int D[]) {
n = N ;
for(int i = 0 ; i < N - 1 ; i++){
grafo[A[i]+1].push_back({B[i]+1, D[i]}) ;
grafo[B[i]+1].push_back({A[i]+1, D[i]}) ;
}
euler.push_back(0) ;
dfs(1, 0) ;
make_cent(1, 0) ;
build() ;
for(int i = 0 ; i < N + 1 ; i++) resp[i] = inf ;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
21 ms |
24272 KB |
Output is correct |
2 |
Correct |
488 ms |
32980 KB |
Output is correct |
3 |
Correct |
624 ms |
38640 KB |
Output is correct |
4 |
Correct |
518 ms |
38512 KB |
Output is correct |
5 |
Correct |
713 ms |
38748 KB |
Output is correct |
6 |
Correct |
256 ms |
38592 KB |
Output is correct |
7 |
Correct |
593 ms |
38508 KB |
Output is correct |
8 |
Correct |
605 ms |
38504 KB |
Output is correct |
9 |
Correct |
725 ms |
38792 KB |
Output is correct |
10 |
Correct |
248 ms |
38456 KB |
Output is correct |
11 |
Correct |
594 ms |
38508 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
24012 KB |
Output is correct |
2 |
Correct |
1975 ms |
161520 KB |
Output is correct |
3 |
Correct |
2710 ms |
166400 KB |
Output is correct |
4 |
Correct |
787 ms |
164988 KB |
Output is correct |
5 |
Correct |
3851 ms |
194848 KB |
Output is correct |
6 |
Correct |
2840 ms |
168192 KB |
Output is correct |
7 |
Correct |
1525 ms |
64052 KB |
Output is correct |
8 |
Correct |
388 ms |
64540 KB |
Output is correct |
9 |
Correct |
1674 ms |
68256 KB |
Output is correct |
10 |
Correct |
1459 ms |
65388 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
21 ms |
24272 KB |
Output is correct |
2 |
Correct |
488 ms |
32980 KB |
Output is correct |
3 |
Correct |
624 ms |
38640 KB |
Output is correct |
4 |
Correct |
518 ms |
38512 KB |
Output is correct |
5 |
Correct |
713 ms |
38748 KB |
Output is correct |
6 |
Correct |
256 ms |
38592 KB |
Output is correct |
7 |
Correct |
593 ms |
38508 KB |
Output is correct |
8 |
Correct |
605 ms |
38504 KB |
Output is correct |
9 |
Correct |
725 ms |
38792 KB |
Output is correct |
10 |
Correct |
248 ms |
38456 KB |
Output is correct |
11 |
Correct |
594 ms |
38508 KB |
Output is correct |
12 |
Correct |
13 ms |
24012 KB |
Output is correct |
13 |
Correct |
1975 ms |
161520 KB |
Output is correct |
14 |
Correct |
2710 ms |
166400 KB |
Output is correct |
15 |
Correct |
787 ms |
164988 KB |
Output is correct |
16 |
Correct |
3851 ms |
194848 KB |
Output is correct |
17 |
Correct |
2840 ms |
168192 KB |
Output is correct |
18 |
Correct |
1525 ms |
64052 KB |
Output is correct |
19 |
Correct |
388 ms |
64540 KB |
Output is correct |
20 |
Correct |
1674 ms |
68256 KB |
Output is correct |
21 |
Correct |
1459 ms |
65388 KB |
Output is correct |
22 |
Correct |
3154 ms |
162700 KB |
Output is correct |
23 |
Correct |
2700 ms |
165112 KB |
Output is correct |
24 |
Correct |
4814 ms |
165296 KB |
Output is correct |
25 |
Correct |
4401 ms |
169828 KB |
Output is correct |
26 |
Correct |
4370 ms |
166740 KB |
Output is correct |
27 |
Correct |
5911 ms |
190740 KB |
Output is correct |
28 |
Correct |
1034 ms |
167328 KB |
Output is correct |
29 |
Correct |
4380 ms |
166828 KB |
Output is correct |
30 |
Correct |
4286 ms |
166100 KB |
Output is correct |
31 |
Correct |
4186 ms |
167432 KB |
Output is correct |
32 |
Correct |
1933 ms |
75812 KB |
Output is correct |
33 |
Correct |
394 ms |
72880 KB |
Output is correct |
34 |
Correct |
1246 ms |
69512 KB |
Output is correct |
35 |
Correct |
1296 ms |
69640 KB |
Output is correct |
36 |
Correct |
1680 ms |
70220 KB |
Output is correct |
37 |
Correct |
1575 ms |
70144 KB |
Output is correct |