제출 #269795

#제출 시각아이디문제언어결과실행 시간메모리
269795shivensinha4경주 (Race) (IOI11_race)C++17
21 / 100
3104 ms188444 KiB
#include <bits/stdc++.h> 
//#include "race.h"
using namespace std; 
#define for_(i, s, e) for (int i = s; i < e; i++)
#define for__(i, s, e) for (ll i = s; i < e; i++)
#define SSTR(x) static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str()
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
//#define endl '\n'

int n, k, l, timer = 0;
vector<vector<pair<int, ll>>> adjList;
vi removed, subtreeSize, centroid, tin, tout;
vector<map<ll, vector<ii>>> paths; // {length, {child, roads}}
vector<vi> up; vector<vector<ll>> upDist;
int ans = 1e9;

int dfs(int p, int parent) {
	int s = 1;
	tin[p] = ++timer;
	
	for_(i, 1, l+1) {
		up[p][i] = up[up[p][i-1]][i-1];
		upDist[p][i] = upDist[p][i-1] + upDist[up[p][i-1]][i-1];
	}
		
	for (auto i: adjList[p]) if (i.first != parent) {
		up[i.first][0] = p;
		upDist[i.first][0] = i.second;
		s += dfs(i.first, p);
	}
	
	subtreeSize[p] = s;
	tout[p] = ++timer;
	return s;
}

bool is_ancestor(int u, int v) {
	return tin[u] <= tin[v] && tout[u] >= tout[v];
}


int lca(int u, int v) {
	if (is_ancestor(u, v)) return u;
	if (is_ancestor(v, u)) return v;
	for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], v)) u = up[u][i];
	
	return up[u][0];
}

// {distance, edges}
pair<ll, int> ancDist(int u, int anc) {
	if (u == anc) return {0, 0};
	
	ll dist = 0, edges = 0;
	for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], anc)) {
		dist += upDist[u][i];
		edges += (1 << i);
		u = up[u][i];
	}
	
	return {dist + upDist[u][0], edges+1};
}

pair<ll, int> dist(int u, int v) {
	int lc = lca(u, v);
	ii a = ancDist(u, lc), b = ancDist(v, lc);
	return {a.first + b.first, a.second + b.second};
}

void decompose(int p, int c) {
	int invalidChild = -1, sizeLimit = (subtreeSize[p] >> 1);
	for (auto i: adjList[p]) if (!removed[i.first] and subtreeSize[i.first] > sizeLimit) {
		invalidChild = i.first;
		break;
	}
	
	if (invalidChild != -1) {
		subtreeSize[p] -= subtreeSize[invalidChild];
		subtreeSize[invalidChild] += subtreeSize[p];
		return decompose(invalidChild, c);
	}
	
	removed[p] = true;
	centroid[p] = c;
	for (auto i: adjList[p]) if (!removed[i.first]) {
		centroid[i.first] = p;
		decompose(i.first, p);
	}
}

void updateParents(int p) {
	int a = p, b = centroid[p];
	while (b != -1) {
		ii d = dist(p, b);
		paths[b][d.first].push_back({d.second, a});
		a = b; b = centroid[b];
	}
}

void solve(int p) {
	int a = p, b = centroid[p];
	while (b != -1) {
		ii d = dist(p, b);
		for (auto o: paths[b][k-d.first]) if (o.second != a) {
			ans = min(ans, o.first + d.second);
			break;
		}
		a = b; b = centroid[b];
	}
}

int best_path(int N, int K, int H[][2], int L[]) {
	n = N, k = K;
	adjList.resize(n); subtreeSize.resize(n); removed.resize(n); paths.resize(n); centroid.resize(n, -1); tin.resize(n); tout.resize(n); up.resize(n);
	l = ceil(log2(n));
	up.assign(n, vi(l+1)); upDist.assign(n, vector<ll>(l+1));
	for_(i, 0, n-1) {
		int a, b; ll w; a = H[i][0], b = H[i][1]; w = L[i];
		adjList[a].push_back({b, w});
		adjList[b].push_back({a, w});
	}
	
	dfs(0, 0);
	decompose(0, -1);
	
	for_(i, 0, n) updateParents(i);
	
	for_(i, 0, n) {
		paths[i][0].push_back({0, -1});
		for (auto o: paths[i]) if (o.second.size() > 1) {
			sort(paths[i][o.first].begin(), paths[i][o.first].begin()+2);
		}
	}
	
	for_(i, 0, n) solve(i);
	
	return (ans == 1e9 ? -1 : ans);
}

//int main() {
	//#ifndef ONLINE_JUDGE
	//freopen("test.in", "r", stdin);
	//#endif
	
	//ios_base::sync_with_stdio(false);
	//cin.tie(0);
	
	//int H[100000][2], L[100000];
	//int N, K;
	//cin >> N >> K;
	//for_(i, 0, N-1) {
		//int a, b; ll w; cin >> a >> b >> w;
		//H[i][0] = a; H[i][1] = b;
		//L[i] = w;
	//}
	
	//cout << best_path(N, K, H, L) << endl;

	//return 0;
//}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...