Submission #1329170

#TimeUsernameProblemLanguageResultExecution timeMemory
1329170yonatanlFactories (JOI14_factories)C++20
15 / 100
8093 ms189644 KiB
#include "factories.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <iomanip>

#define rep(i, s, e) for (ll i = s; i < e; i++)
#define upmax(a, b) a = max(a, b)
#define upmin(a, b) a = min(a, b)

using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using pll = pair<ll, ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;

const ll INF = 1e18;

vvpll tree;
vll is_removed;
vll sz, min_dist;
vvpll ancestors;


ll get_centroid(ll node, ll papa, ll cur_sz) {
	for (auto& it : tree[node]) {
		ll nei = it.first;
		if (nei == papa || is_removed[nei]) continue;
		if (sz[nei] > cur_sz / 2) {
			return get_centroid(nei, node, cur_sz);
		}
	}
	return node;
}

ll get_subtree_size(ll node, ll papa) {
	sz[node] = 1;
	for (auto& it : tree[node]) {
		ll nei = it.first;
		if (nei == papa || is_removed[nei]) continue;
		sz[node] += get_subtree_size(nei, node);
	}
	return sz[node];
}

void get_dists(ll node, ll centroid, ll papa, ll cur_dist) {
	for (auto& it : tree[node]) {
		ll nei = it.first, w = it.second;
		if (nei == papa || is_removed[nei]) continue;
		get_dists(nei, centroid, node, cur_dist + w);
	}
	ancestors[node].push_back({ centroid, cur_dist });
}

void centroid_decomp(ll node) {
	ll cur_sz = get_subtree_size(node, -1);
	ll centroid = get_centroid(node, -1, cur_sz);
	is_removed[centroid] = true;
	for (auto& it : tree[centroid]) {
		ll nei = it.first, w = it.second;
		if (is_removed[nei]) continue;
		get_dists(nei, centroid, centroid, w);
		centroid_decomp(nei);
	}
}

void update(ll node) {
	min_dist[node] = 0;
	rep(i, 0, ancestors[node].size()) {
		ll ancestor = ancestors[node][i].first;
		ll dist = ancestors[node][i].second;
		upmin(min_dist[ancestor], dist);
	}
}

ll query(ll node) {
	ll res = min_dist[node];
	rep(i, 0, ancestors[node].size()) {
		ll ancestor = ancestors[node][i].first;
		ll dist = ancestors[node][i].second;
		upmin(res, min_dist[ancestor] + dist);
	}
	return res;
}

void Init(int N, int A[], int B[], int D[]) {
	ll n = N;
	tree.clear(), tree.resize(n);
	is_removed.clear(), is_removed.resize(n);
	sz.clear(), sz.resize(n);
	ancestors.clear(), ancestors.resize(n);
	min_dist.clear(), min_dist.resize(n, INF);
	rep(i, 0, n - 1) {
		ll a, b, c;
		a = A[i], b = B[i], c = D[i];
		tree[a].push_back({ b, c });
		tree[b].push_back({ a, c });
	}
	centroid_decomp(0);
}

long long Query(int S, int X[], int T, int Y[]) {
	ll sz_a = S, sz_b = T;
	ll ans = INF;
	rep(i, 0, sz_a) {
		ll node = X[i];
		update(node);
	}
	rep(i, 0, sz_b) {
		ll node = Y[i];
		upmin(ans, query(node));
	}
	fill(min_dist.begin(), min_dist.end(), INF);
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...