Pagini recente » Cod sursa (job #297449) | Cod sursa (job #1643628) | Cod sursa (job #2638982) | Cod sursa (job #2611138) | Cod sursa (job #3241596)
#include <bits/stdc++.h>
using namespace std;
class DisjointSet {
private:
vector<int> root;
vector<int> size;
public:
DisjointSet(int n)
: root(n + 1)
, size(n + 1) {
for (int node = 1; node <= n; ++node) {
root[node] = node;
size[node] = 1;
}
}
int pathCompression(int node) {
if (node == root[node]) {
return node;
}
root[node] = pathCompression(root[node]);
return root[node];
}
void unionByRank(int x, int y) {
int rx = pathCompression(x), ry = pathCompression(y);
if (rx != ry) {
if (size[rx] <= size[ry]) {
size[ry] += size[rx];
root[rx] = ry;
} else {
size[rx] += size[ry];
root[ry] = rx;
}
}
}
};
class Task {
public:
void solve() {
read_input();
process();
print_output();
}
private:
int n, m, k;
vector<tuple<int, int, int>> edges;
vector<pair<int, int>> queries;
vector<int> results;
vector<vector<pair<int, int>>> adj;
vector<vector<int>> up;
vector<vector<int>> maxEdge;
vector<int> depth;
const int LOG = 15; // log2(15000) = 14
void read_input() {
ifstream fin("radiatie.in");
fin >> n >> m >> k;
edges.resize(m);
queries.resize(k);
adj.resize(n + 1);
up.resize(n + 1, vector<int>(LOG));
maxEdge.resize(n + 1, vector<int>(LOG));
depth.resize(n + 1);
for (int i = 0, a, b, c; i < m; ++i) {
fin >> a >> b >> c;
edges[i] = {c, a, b};
}
for (int i = 0, x, y; i < k; ++i) {
fin >> x >> y;
queries[i] = {x, y};
}
fin.close();
}
void process() {
// Step 1: Sort edges by weight and create MST using Kruskal's algorithm
sort(edges.begin(), edges.end());
DisjointSet dsu(n);
for (auto [c, a, b] : edges) {
if (dsu.pathCompression(a) != dsu.pathCompression(b)) {
dsu.unionByRank(a, b);
adj[a].emplace_back(b, c);
adj[b].emplace_back(a, c);
}
}
// Step 2: Preprocess LCA and max edge info
dfs(1, 0, 0, 0);
// Step 3: Process each query
for (auto [x, y] : queries) {
results.push_back(getMaxEdgeInPath(x, y));
}
}
void dfs(int node, int parent, int d, int w) {
depth[node] = d;
up[node][0] = parent;
maxEdge[node][0] = w;
for (int i = 1; i < LOG; ++i) {
up[node][i] = up[up[node][i - 1]][i - 1];
maxEdge[node][i] = max(maxEdge[node][i - 1], maxEdge[up[node][i - 1]][i - 1]);
}
for (auto [neighbor, weight] : adj[node]) {
if (neighbor != parent) {
dfs(neighbor, node, d + 1, weight);
}
}
}
int getMaxEdgeInPath(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
int maxEdgeInPath = 0;
// Bring u and v to the same depth
for (int i = LOG - 1; i >= 0; --i) {
if (depth[u] - (1 << i) >= depth[v]) {
maxEdgeInPath = max(maxEdgeInPath, maxEdge[u][i]);
u = up[u][i];
}
}
if (u == v) {
return maxEdgeInPath;
}
// Bring u and v to their LCA
for (int i = LOG - 1; i >= 0; --i) {
if (up[u][i] != up[v][i]) {
maxEdgeInPath = max({maxEdgeInPath, maxEdge[u][i], maxEdge[v][i]});
u = up[u][i];
v = up[v][i];
}
}
// Final step to reach LCA
return max({maxEdgeInPath, maxEdge[u][0], maxEdge[v][0]});
}
void print_output() {
ofstream fout("radiatie.out");
for (int result : results) {
fout << result << "\n";
}
fout.close();
}
};
int main() {
ios::sync_with_stdio(false);
auto* task = new (nothrow) Task();
if (!task) {
cerr << "new failed\n";
return -1;
}
task->solve();
delete task;
return 0;
}