Pagini recente » Cod sursa (job #651807) | Cod sursa (job #327251) | Cod sursa (job #811790) | Cod sursa (job #2825307) | Cod sursa (job #3031420)
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
const int MAX_N = 15005;
struct Edge {
int a, b;
int cost;
inline bool operator < (const Edge& other) const {
return cost < other.cost;
}
};
int n, m, k;
int fathers[MAX_N];
int depth[MAX_N];
vector <Edge> edges;
vector <Edge> graph[MAX_N];
vector <Edge> opGraph[MAX_N];
int parent[MAX_N];
int ancestors[20][MAX_N];
void InitAPM() {
sort(edges.begin(), edges.end());
for (int i = 1; i <= n; i++) {
fathers[i] = i;
depth[i] = 1;
}
}
int FindRoot(int node) {
if (node == fathers[node]) {
return node;
}
return fathers[node] = FindRoot(fathers[node]);
}
void Union(int a, int b, int cost) {
int originalA = a;
int originalB = b;
a = FindRoot(a);
b = FindRoot(b);
if (depth[a] < depth[b]) {
fathers[a] = b;
graph[originalB].push_back({originalB, originalA, cost});
opGraph[originalA].push_back({originalA, originalB, cost});
}
else if (depth[b] < depth[a]) {
fathers[b] = a;
graph[originalA].push_back({originalA, originalB, cost});
opGraph[originalB].push_back({originalB, originalA, cost});
}
else {
fathers[a] = b;
depth[b]++;
graph[originalB].push_back({originalB, originalA, cost});
opGraph[originalA].push_back({originalA, originalB, cost});
}
}
void BuildAPM() {
InitAPM();
for (Edge edge : edges) {
if (FindRoot(edge.a) == FindRoot(edge.b)) {
continue;
}
Union(edge.a, edge.b, edge.cost);
}
}
void BuildDepths(int node, int d) {
depth[node] = d;
for (Edge newEdge : graph[node]) {
BuildDepths(newEdge.b, d + 1);
}
}
void BuildLCA() {
for (int i = 1; i <= n; i++) {
if (!graph[i].empty()) {
for (Edge edge : graph[i]) {
ancestors[0][edge.b] = i;
}
}
}
for (int e = 1; e < 19; e++) {
for (int node = 1; node <= n; node++) {
ancestors[e][node] = ancestors[e - 1][ancestors[e - 1][node]];
}
}
BuildDepths(FindRoot(1), 1);
}
int LCAQuery(int a, int b) {
if (depth[a] < depth[b]) {
swap(a, b);
}
int depthDiff = depth[a] - depth[b];
for (int e = 0; e < 19; e++) {
if (depthDiff & (1 << e)) {
a = ancestors[e][a];
}
}
if (a == b) {
return a;
}
for (int e = 18; e >= 0; e--) {
if (ancestors[e][a] != ancestors[e][b]) {
a = ancestors[e][a];
b = ancestors[e][b];
}
}
return ancestors[0][a];
}
void DFSToNode(int node, int destination, int& maxValue) {
if (node == destination) {
return;
}
for (Edge edge : opGraph[node]) {
maxValue = max(maxValue, edge.cost);
DFSToNode(edge.b, destination, maxValue);
}
}
void BuildAnswer() {
for (int i = 1; i <= k; i++) {
int a, b;
fin >> a >> b;
int root = LCAQuery(a, b);
int maxValueToA = 0;
DFSToNode(a, root, maxValueToA);
int maxValueToB = 0;
DFSToNode(b, root, maxValueToB);
fout << max(maxValueToA, maxValueToB) << '\n';
}
}
int main() {
fin >> n >> m >> k;
for (int i = 1; i <= m; i++) {
int a, b, cost;
fin >> a >> b >> cost;
edges.push_back({a, b, cost});
}
BuildAPM();
BuildLCA();
BuildAnswer();
}