Pagini recente » Cod sursa (job #1109069) | Cod sursa (job #2153539) | Cod sursa (job #1767915) | Cod sursa (job #2691482) | Cod sursa (job #3327218)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("radiatie.in");
ofstream cout("radiatie.out");
using ll = long long;
const int MAXN = 15000 + 5;
const int LOG = 17;
struct Edge {
int u, v;
ll w;
bool operator<(Edge const& other) const { return w < other.w; }
};
struct DSU {
vector<int> p, sz;
DSU(int n=0){ init(n); }
void init(int n){
p.resize(n+1);
sz.resize(n+1);
for(int i=1;i<=n;i++){
p[i]=i;
sz[i]=1;
}
}
int find(int x){
return p[x]==x ? x : p[x]=find(p[x]);
}
bool unite(int a,int b){
a=find(a);
b=find(b);
if(a==b) return false;
if(sz[a]<sz[b]) swap(a,b);
p[b]=a;
sz[a]+=sz[b];
return true;
}
};
int n, m, k;
vector<Edge> edges;
vector<vector<pair<int,ll>>> adj;
int up[MAXN][LOG];
ll maxUp[MAXN][LOG];
int depthArr[MAXN];
int tin[MAXN], tout[MAXN], timerCnt;
void dfs(int u, int parent){
tin[u] = ++timerCnt;
up[u][0] = parent;
for(auto &pr : adj[u]){
int v = pr.first;
ll w = pr.second;
if(v == parent) continue;
depthArr[v] = depthArr[u] + 1;
maxUp[v][0] = w;
dfs(v, u);
}
tout[u] = ++timerCnt;
}
bool isAncestor(int a, int b){
return tin[a] <= tin[b] && tout[b] <= tout[a];
}
ll getMaxOnPath(int a, int b){
if(a == b) return 0;
ll ans = 0;
if(depthArr[a] < depthArr[b]) swap(a,b);
int diff = depthArr[a] - depthArr[b];
for(int j=0;j<LOG;j++){
if(diff & (1<<j)){
ans = max(ans, maxUp[a][j]);
a = up[a][j];
}
}
if(a == b) return ans;
for(int j=LOG-1;j>=0;j--){
if(up[a][j] != 0 && up[a][j] != up[b][j]){
ans = max(ans, maxUp[a][j]);
ans = max(ans, maxUp[b][j]);
a = up[a][j];
b = up[b][j];
}
}
ans = max(ans, maxUp[a][0]);
ans = max(ans, maxUp[b][0]);
return ans;
}
int main(){
cin >> n >> m >> k;
edges.reserve(m);
for(int i=0;i<m;i++){
int a,b;
ll c;
cin >> a >> b >> c;
edges.push_back({a,b,c});
}
vector<pair<int,int>> queries(k);
for(int i=0;i<k;i++){
int x,y;
cin >> x >> y;
queries[i] = {x,y};
}
sort(edges.begin(), edges.end());
DSU dsu(n);
adj.assign(n+1, {});
for(auto &e: edges){
if(dsu.unite(e.u, e.v)){
adj[e.u].push_back({e.v, e.w});
adj[e.v].push_back({e.u, e.w});
}
}
for(int i=1;i<=n;i++){
depthArr[i] = 0;
for(int j=0;j<LOG;j++){
up[i][j] = 0;
maxUp[i][j] = 0;
}
tin[i]=0;
tout[i]=0;
}
timerCnt = 0;
for(int i=1;i<=n;i++){
if(tin[i]==0){
up[i][0] = 0;
maxUp[i][0] = 0;
depthArr[i] = 0;
dfs(i, 0);
}
}
for(int j=1;j<LOG;j++){
for(int v=1; v<=n; v++){
int mid = up[v][j-1];
up[v][j] = mid ? up[mid][j-1] : 0;
maxUp[v][j] = maxUp[v][j-1];
if(mid) maxUp[v][j] = max(maxUp[v][j], maxUp[mid][j-1]);
}
}
for(auto &qr : queries){
cout << getMaxOnPath(qr.first, qr.second) << '\n';
}
return 0;
}