답안 #532470

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
532470 2022-03-03T00:57:10 Z Pietra 공장들 (JOI14_factories) C++14
100 / 100
5911 ms 194848 KB
// 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