제출 #874963

#제출 시각아이디문제언어결과실행 시간메모리
874963YassirSalama공장들 (JOI14_factories)C++17
33 / 100
8090 ms195604 KiB
#include"factories.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <iomanip>
#include <cmath>
#include <limits>
#include <map>
#include <utility>
#include <cctype>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <functional>
#include <iterator>
#include<assert.h>
using namespace std;
#define OVL(x,s) for(auto y:x) cout<<y<<s; cout<<"\n";
void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }
#define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__);
#define endl "\n"
#define pb push_back
#define F first
#define S second
#define ll long long
#define mod 1000000007
#define all(v) v.begin(),v.end()
const int MAXN=5e5+100;
const int LOGN=21;
int up[MAXN][LOGN];
set<pair<int,int>> v[MAXN];
ll depth[MAXN];
int depth1[MAXN];
int par[MAXN];
int sub[MAXN];
bool visited[MAXN];
ll ans[MAXN];
void dfs(int node,int par){
	depth1[node]=depth1[par]+1;
	up[node][0]=par;
	for(int i=1;i<LOGN;i++){
		up[node][i]=up[up[node][i-1]][i-1];
	}
	for(auto x:v[node]){
		if(x.F==par) continue;
		depth[x.F]=depth[node]+x.S;
		dfs(x.F,node);
	}
}
int LCA(int a,int b){
	if(depth1[a]<depth1[b]) swap(a,b);
	ll d=depth1[a]-depth1[b];
	for(ll i=LOGN-1;i>=0;i--){
		if(d&(1<<i)) a=up[a][i]; 
	}
	if(a==b) return a;
	for(ll i=LOGN-1;i>=0;i--){
		if(up[a][i]==up[b][i]) continue;
		a=up[a][i];
		b=up[b][i];
	}
	return up[a][0];
}
ll dist(int a,int b){
	return depth[a]+depth[b]-2*depth[LCA(a,b)];
}
int dfs1(int node,int par){
	sub[node]=1;
	for(auto x:v[node]) {
	    if(x.F==par) continue;
	    sub[node]+=dfs1(x.F,node);
	}
	return sub[node];
}
int dfs2(int node,int par,int n){
	for(auto x:v[node]){
		if(x.F!=par&&sub[x.F]>n/2)
			return dfs2(x.F,node,n);
	}
	return node;
}
void build(int u, int p) {
  int n = dfs1(u, p);
  int c = dfs2(u, p, n);
  par[c] = p;

  // vector<pair<int,int>> tmp(v[c].begin(), v[c].end());
  for(auto x : v[c]) {
  	if(x.F==p) continue;
    // v[c].erase({x.F,x.S}); 
    v[x.F].erase({c,x.S});
    build(x.F, c);
  }
}
void Init(int N, int A[], int B[], int D[]){
	for(int i=0;i<N-1;i++){
		v[A[i]].insert({B[i],D[i]});
		v[B[i]].insert({A[i],D[i]});
	}
	dfs(0,0);
	build(0,-1);
	for(int i=0;i<=N;i++) ans[i]=1e18;
}
long long Query(int S, int X[], int T, int Y[]){
	ll anss=1e18;
	for(int i=0;i<T;i++){
		int node=Y[i];
		while(node!=-1){
			ans[node]=min(ans[node],dist(Y[i],node));
			node=par[node];
		}
	}
	for(int i=0;i<S;i++) {
		int node=X[i];
		while(node!=-1){
			anss=min(anss,ans[node]+dist(X[i],node));
			node=par[node];
		}
	}
	for(int i=0;i<T;i++){
		int node=Y[i];
		while(node!=-1){
			if(ans[node]==(int)1e18) break;
			ans[node]=1e18;
			node=par[node];
		}
	}	return anss;
}

#ifdef IOI


int main(){
	// Init(7, {0, 1, 2, 2, 4, 1}, {1, 2, 3, 4, 5, 6}, {4, 4, 5, 6, 5, 3});
	// cout<<Query(2, 2, {0, 6}, {3, 4}); //returns 12.
	// cout<<endl<<Query(3, 2, {0, 1, 3}, {4, 6}); //returns 3.
	// cout<<endl<<Query(1, 1, {2}, {5}); //returns 11.
	// return 0;
    int N, Q;
    assert(scanf("%i %i", &N, &Q) == 2);
    int *A = (int*)malloc(sizeof(int) * (N - 1));
    int *B = (int*)malloc(sizeof(int) * (N - 1));
    int *D = (int*)malloc(sizeof(int) * (N - 1));
    for(int a = 0; a < N - 1; a++){
        assert(scanf("%i %i %i", A + a, B + a, D + a) == 3);
    }
    Init(N, A, B, D);
    for(int a = 0; a < Q; a++){
        int S, T;
        assert(scanf("%i %i", &S, &T) == 2);
        int *X = (int*)malloc(sizeof(int) * S);
        int *Y = (int*)malloc(sizeof(int) * T);
        for(int b = 0; b < S; b++){
            assert(scanf("%i", X + b) == 1);
        }
        for(int b = 0; b < T; b++){
            assert(scanf("%i", Y + b) == 1);
        }
        printf("%i\n", Query(S, X, T, Y));
        free(X);
        free(Y);
    }
    free(A);
    free(B);
    free(D);
}
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...