Pagini recente » Cod sursa (job #2760420) | Cod sursa (job #2525404) | Cod sursa (job #1182857) | Cod sursa (job #2416391) | Cod sursa (job #3269617)
#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';
}
}