제출 #116458

#제출 시각아이디문제언어결과실행 시간메모리
116458YazanZkFactories (JOI14_factories)C++17
0 / 100
126 ms122488 KiB
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

/***************  LCA  ******************/

const int N = 5 * 1e5 + 1 ;
const int Log = 19;
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[i][j - 1]] ;
}

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];
}

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...