Pagini recente » Cod sursa (job #2366041) | Cod sursa (job #2281246) | Cod sursa (job #2746848) | Cod sursa (job #1855415) | Cod sursa (job #1657154)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
ifstream cin("radiatie.in");
ofstream cout("radiatie.out");
const int MaxM = 300005, LogMaxM = 20, MaxN = 15005;
vector <int> Tree[MaxN];
int dsu_depth[MaxN], father[MaxN], anc_table[LogMaxM][MaxN], max_table[LogMaxM][MaxN], lvl[MaxN];
int n, m, k, log2n, msp_root, max_tunnel;
class Edge {
public:
int n1, n2, cost;
};
vector <Edge> edg, msp_list;
void dsu_init() {
for(int i = 1; i <= n; ++i) {
dsu_depth[i] = 1;
father[i] = i;
}
}
int find_root(int node) {
if(node == father[node]) {
return node;
}
return father[node] = find_root(father[node]);
}
void dsu_merge(const int &node1, const int &node2) {
int root1 = find_root(node1);
int root2 = find_root(node2);
if(dsu_depth[root1] < dsu_depth[root2]) {
father[root1] = root2;
}
else if(dsu_depth[root2] < dsu_depth[root1]) {
father[root2] = root1;
}
else {
father[root2] = root1;
++dsu_depth[root1];
}
}
inline bool EdgeSort(const Edge &a, const Edge &b) {
return a.cost < b.cost;
}
void MSP() {
sort(edg.begin(), edg.end(), EdgeSort);
for(auto it: edg) {
if(find_root(it.n1) == find_root(it.n2)) {
continue;
}
dsu_merge(it.n1, it.n2);
msp_list.push_back({it.n1, it.n2, it.cost});
}
}
void AncTable_init() {
for(auto it: msp_list) {
Tree[it.n1].push_back(it.n2);
Tree[it.n2].push_back(it.n1);
if(anc_table[0][it.n2]) {
anc_table[0][it.n1] = it.n2;
max_table[0][it.n1] = it.cost;
}
else/* if(anc_table[0][it.n1])*/ {
anc_table[0][it.n2] = it.n1;
max_table[0][it.n2] = it.cost;
}
}
for(int i = 1; i <= n; ++i) {
if(!anc_table[0][i]) {
anc_table[0][i] = i;
msp_root = i;
break;
}
}
for(int i = 1; i <= log2n; ++i) {
for(int j = 1; j <= n; ++j) {
anc_table[i][j] = anc_table[i - 1][anc_table[i - 1][j]];
max_table[i][j] = max(max_table[i - 1][j], max_table[i - 1][anc_table[i - 1][j]]);
}
}
}
void lvl_init(int node, int level) {
lvl[node] = level;
for(auto nxt: Tree[node]) {
if(lvl[nxt]) {
continue;
}
lvl_init(nxt, level + 1);
}
}
void EqLevel(int &nodeLo, int &nodeHi) {
if(lvl[nodeLo] < lvl[nodeHi]) {
swap(nodeLo, nodeHi);
}
int diff = lvl[nodeLo] - lvl[nodeHi];
for(int i = log2(diff); i >= 0 and diff; --i) {
if(diff - (1 << i) >= 0) {
diff -= (1 << i);
max_tunnel = max(max_tunnel, max_table[i][nodeLo]);
nodeLo = anc_table[i][nodeLo];
}
}
}
inline int max3(int a, int b, int c) {
int ans = a;
if(b > ans) {
ans = b;
}
if(c > ans) {
ans = c;
}
return ans;
}
void LCA(int node1, int node2) {
if(node1 == node2) {
return;
}
for(int i = log2n; i >= 0; --i) {
if(anc_table[i][node1] != anc_table[i][node2]) {
node1 = anc_table[i][node1];
node2 = anc_table[i][node2];
max_tunnel = max3(max_tunnel, max_table[i][node1], max_table[i][node2]);
}
}
max_tunnel = max3(max_tunnel, max_table[0][node1], max_table[0][node2]);
}
int main() {
cin >> n >> m >> k;
log2n = log2(n);
for(int i = 1; i <= m; ++i) {
int a, b, d;
cin >> a >> b >> d;
edg.push_back({a, b, d});
}
dsu_init();
MSP();
AncTable_init();
lvl_init(msp_root, 1);
for(int i = 1; i <= k; ++i) {
int node1, node2;
max_tunnel = 0;
cin >> node1 >> node2;
EqLevel(node1, node2);
LCA(node1, node2);
cout << max_tunnel << '\n';
}
return 0;
}