Cod sursa(job #2941669)

Utilizator IanisBelu Ianis Ianis Data 18 noiembrie 2022 01:34:37
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <bitset>
#include <stack>
#include <queue>
#include <deque>

using namespace std;

#ifdef LOCAL
ifstream fin("input.txt");
#define fout cout
#else
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
#endif

const int NMAX = 15005;
const int LOGN = 20;

struct Edge {
	int x, y, c;
};

int n, m, k;
vector<pair<int, int>> tree[NMAX];
vector<int> euler;
int up[NMAX][LOGN];
int rmq[NMAX][LOGN];
int lca[2 * NMAX][LOGN];
int depth[NMAX];
int parent[NMAX];
int parent_dist[NMAX];
Edge e[2 * NMAX];
int l[NMAX], r[NMAX];
bool viz[NMAX];

int root(int x) {
	if (r[x] == x)
		return x;
	return r[x] = root(r[x]);
}

void merge(const Edge &e) {
	tree[e.x].push_back({e.y, e.c});
	tree[e.y].push_back({e.x, e.c});
	r[root(e.x)] = root(e.y);
}

bool cmp(const Edge &a, const Edge &b) {
	return a.c < b.c;
}

void apm() {
	for (int i = 1; i <= n; i++)
		r[i] = i;

	sort(e + 1, e + m + 1, cmp);

	for (auto &it : e) {
		if (root(it.x) != root(it.y))
			merge(it);
	}
}

void dfs(int x) {
	viz[x] = true;
	l[x] = euler.size();
	euler.push_back(x);
	for (auto &it : tree[x]) {
		int v = it.first;
		int c = it.second;
		if (!viz[v]) {
			parent[v] = x;
			depth[v] = depth[x] + 1;
			parent_dist[v] = c;
			dfs(v);
			euler.push_back(x);
		}
	}
}

void precalc() {
	apm();
	dfs(1);
	for (int i = 1; i <= n; i++)
		up[i][0] = parent[i];
	for (int j = 1; 1 << j <= n; j++)
		for (int i = 1; i <= n; i++)
			up[i][j] = up[up[i][j-1]][j - 1];

	for (int i = 1; i <= n; i++)
		rmq[i][0] = parent_dist[i];
	for (int j = 1; 1 << j <= n; j++) {
		for (int i = 1; i <= n; i++) {
			int a = rmq[i][j - 1];
			int b = rmq[up[i][j - 1]][j - 1];
			rmq[i][j] = max(a, b);
		}
	}
	
	for (int i = 0; i < euler.size(); i++)
		lca[i][0] = i;
	for (int j = 1; 1 << j <= euler.size(); j++)
		for (int i = 0; i + (1 << j) - 1 < euler.size(); i++) {
			int a = lca[i][j - 1];
			int b = lca[i + (1 << (j - 1))][j - 1];
			lca[i][j] = depth[euler[a]] < depth[euler[b]] ? a : b;
		}
}

int query_rmq(int a, int b) {
	if (depth[a] < depth[b])
		swap(a, b);
	int k = log2(depth[a] - depth[b]);
	int mx = 0;
	for (int i = k; i >= 0; i--)
		if (depth[a] - depth[b] >= 1 << i) {
			mx = max(rmq[a][i], mx);
			a = up[a][i];
		}
	return mx;
}

int query_lca(int a, int b) {
	a = l[a], b = l[b];
	if (a > b)
		swap(a, b);
	int k = log2(b - a + 1);
	int x = euler[lca[a][k]];
	int y = euler[lca[b - (1 << k) + 1][k]];
	return depth[x] < depth[y] ? x : y;
}

int solve(int a, int b) {
	int lca = query_lca(a, b);
	return max(query_rmq(a, lca), query_rmq(b, lca));
}

int32_t main() {
	fin >> n >> m >> k;
	for (int i = 1; i <= m; i++)
		fin >> e[i].x >> e[i].y >> e[i].c;
	precalc();
	while (k--) {
		int x, y;
		fin >> x >> y;
		fout << solve(x, y) << '\n';
	}
	return 0;
}