Pagini recente » Cod sursa (job #1701637) | Cod sursa (job #3189405) | Cod sursa (job #1549700) | Cod sursa (job #1692329) | Cod sursa (job #2524950)
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
struct Edge{
int x, y, cost;
bool operator < (const Edge& other) const
{
return cost < other.cost;
}
};
using VI = vector<int>;
using VVI = vector<VI>;
using VB = vector<bool>;
using PII = pair<int, int>;
using VP = vector<PII>;
using VVP = vector<VP>;
int N, M, K;
VVP G;
VI f, w;
vector<Edge> edges;
VI h, t; // Union-find
VVI dp, c;
VI lv;
int lvmax, lg;
void ReadData();
void Solve();
void Kruskal();
void DFS(int node, int p);
void Union(int x, int y);
int Find(int x);
void Precalc();
int Query(int x, int y);
int main()
{
ReadData();
Solve();
fin.close();
fout.close();
return 0;
}
void ReadData()
{
fin >> N >> M >> K;
edges = vector<Edge>(M);
G = VVP(N + 1);
for (int i = 0; i < M; ++i)
fin >> edges[i].x >> edges[i].y >> edges[i].cost;
}
void Solve()
{
Kruskal();
Precalc();
int x, y;
while (K--)
{
fin >> x >> y;
fout << Query(x, y) << '\n';
}
}
void Kruskal()
{
h = t = VI(N + 1);
for (int i = 1; i <= N; ++i)
t[i] = i;
sort(edges.begin(), edges.end());
int cnt{0};
for (const Edge& e : edges)
{
int x = e.x;
int y = e.y;
int c = e.cost;
int c1 = Find(x);
int c2 = Find(y);
if (c1 == c2)
continue;
G[x].emplace_back(y, c);
G[y].emplace_back(x, c);
Union(c1, c2);
++cnt;
if (cnt == N - 1)
break;
}
}
void DFS(int node, int p)
{
f[node] = p;
lv[node] = lv[p] + 1;
lvmax = max(lvmax, lv[node]);
for (const auto& v : G[node])
{
if (v.first == p)
continue;
w[v.first] = v.second;
DFS(v.first, node);
}
}
void Union(int x, int y)
{
if (h[x] < h[y])
t[x] = y;
else
{
t[y] = x;
if (h[x] == h[y])
++h[x];
}
}
int Find(int x)
{
if (x == t[x])
return x;
return t[x] = Find(t[x]);
}
void Precalc()
{
f = w = VI(N + 1);
lv = VI(N + 1);
DFS(1, 0);
// for (int i = 1; i <= N; ++i)
// cout << i << ' ' << f[i] << '\n';
lg = 0;
while ((1 << lg) <= lvmax)
++lg;
dp = c = VVI(lg + 1, VI(N + 1));
dp[0][1] = c[0][1] = 0;
for (int i = 2; i <= N; ++i)
{
dp[0][i] = f[i];
c[0][i] = w[i];
//cout << i << ' ' << w[i] << '\n';
}
for (int k = 1; k <= lg; ++k)
for (int i = 1; i <= N; ++i)
{
dp[k][i] = dp[k - 1][dp[k - 1][i]];
c[k][i] = max(c[k - 1][i], c[k - 1][dp[k - 1][i]]);
}
}
int Query(int x, int y)
{
if (lv[x] > lv[y])
return Query(y, x);
int ans{0};
int t = lg;
while (t >= 0 && lv[x] != lv[y])
{
if (lv[dp[t][y]] >= lv[x])
{
ans = max(ans, c[t][y]);
y = dp[t][y];
}
--t;
}
//cout << ans << ' ' << x << ' ' << y << '\n';
t = lg;
while (t >= 0 && x != y)
{
if (dp[t][x] != dp[t][y])
{
ans = max(ans, max(c[t][x], c[t][y]));
x = dp[t][x];
y = dp[t][y];
}
--t;
}
if (x != y)
ans = max(ans, max(w[x], w[y]));
return ans;
}