Cod sursa(job #3269617)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 20 ianuarie 2025 00:24:09
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

#define MAXN 15005

struct Edge {
	int a, b, c;

	bool operator < (const Edge& other) const {
		return c < other.c;
	}
};

struct Node {
	int a, c;
};

int n, m, k;
vector<Edge> edges;
vector<Node> rawGraph[MAXN];
vector<Node> graph[MAXN];
int parent[MAXN];
int depth[MAXN];
bool visited[MAXN];
int ancestors[18][MAXN];
int rmq[18][MAXN];

int FindRoot(int node) {
	if (parent[node] == node) {
		return node;
	}
	return parent[node] = FindRoot(parent[node]);
}

void Union(int a, int b) {
	a = FindRoot(a);
	b = FindRoot(b);

	if (depth[a] == depth[b]) {
		depth[a]++;
		parent[b] = a;
	}
	else if (depth[a] > depth[b]) {
		parent[b] = a;
	} else {
		parent[a] = b;
	}
}

void BuildTree(Node prev, Node node) {
	visited[node.a] = true;
	for (Node newNode : rawGraph[node.a]) {
		if (visited[newNode.a]) {
			continue;
		}
		ancestors[0][newNode.a] = node.a;
		rmq[0][newNode.a] = newNode.c;
		graph[node.a].push_back(newNode);
		BuildTree(node, newNode);
	}
}

void BuildAncestors(Node node, int d) {
	depth[node.a] = d;
	for (int e = 1; e < 18; e++) {
		ancestors[e][node.a] = ancestors[e - 1][ancestors[e - 1][node.a]];
		rmq[e][node.a] = max(rmq[e - 1][node.a], rmq[e - 1][ancestors[e - 1][node.a]]);
	}
	for (Node newNode : graph[node.a]) {
		BuildAncestors(newNode, d + 1);
	}
}

int GetLCA(int a, int b) {
	if (depth[a] < depth[b]) {
		swap(a, b);
	}
	int ans = -1;
	int dif = depth[a] - depth[b];
	for (int e = 0; e < 18; e++) {
		if ((1 << e) & dif) {
			ans = max(ans, rmq[e][a]);
			a = ancestors[e][a];
		}
	}
	int savedA = a;
	int savedB = b;
	if (a == b) {
		return ans;
	}
	for (int e = 17; e >= 0; e--) {
		if (ancestors[e][a] == ancestors[e][b]) {
			continue;
		}
		a = ancestors[e][a];
		b = ancestors[e][b];
	}
	int lca = ancestors[0][a];
	dif = depth[savedA] - depth[lca];
	a = savedA;
	for (int e = 0; e < 18; e++) {
		if ((1 << e) & dif) {
			ans = max(ans, rmq[e][a]);
			a = ancestors[e][a];
		}
	}

	dif = depth[savedB] - depth[lca];
	b = savedB;
	for (int e = 0; e < 18; e++) {
		if ((1 << e) & dif) {
			ans = max(ans, rmq[e][b]);
			b = ancestors[e][b];
		}
	}
	cout << ans;
	return ans;
}

int main() {
	fin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		depth[i] = 1;
		parent[i] = i;
	}
	for (int i = 0; i < m; i++) {
		int a, b, c;
		fin >> a >> b >> c;
		edges.push_back({a, b, c});
	}
	sort(edges.begin(), edges.end());
	for (Edge edge : edges) {
		if (FindRoot(edge.a) == FindRoot(edge.b)) {
			continue;
		}
		Union(edge.a, edge.b);
		rawGraph[edge.a].push_back({edge.b, edge.c});
		rawGraph[edge.b].push_back({edge.a, edge.c});
	}
	BuildTree({-1, 0}, {1, 0});
	BuildAncestors({1, 0}, 1);
	for (int i = 0; i < k; i++) {
		int a, b;
		fin >> a >> b;
		fout << GetLCA(a, b) << '\n';
	}
}