Pagini recente » Cod sursa (job #2529997) | Cod sursa (job #2768977) | Cod sursa (job #3229644) | Cod sursa (job #2725771) | Cod sursa (job #2961219)
#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;
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;
class TreeEdge
{
public:
int node, cost;
};
vector<TreeEdge> Tree[MaxN];
void dsu_init()
{
for (int i = 1; i <= n; ++i)
{
dsu_depth[i] = 1;
father[i] = i;
}
}
int find_root(const 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()
{ /// Minimum Spanning Pom
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);
Tree[it.n1].push_back({it.n2, it.cost});
Tree[it.n2].push_back({it.n1, it.cost});
}
}
void AncTable_init()
{
for (int i = 1; i <= n; ++i)
{
if (!anc_table[0][i])
{
anc_table[0][i] = i;
}
}
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 dfs(int curr, int level)
{
lvl[curr] = level;
for (auto nxt : Tree[curr])
{
if (lvl[nxt.node])
{
continue;
}
anc_table[0][nxt.node] = curr;
max_table[0][nxt.node] = nxt.cost;
dfs(nxt.node, 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])
{
max_tunnel = max3(max_tunnel, max_table[i][node1], max_table[i][node2]);
node1 = anc_table[i][node1];
node2 = anc_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();
for (int i = 1; i <= n; ++i)
{
if (lvl[i])
{
continue;
}
dfs(i, 1);
}
AncTable_init();
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;
}