Cod sursa(job #3327218)

Utilizator vladneaguVladneagu vladneagu Data 2 decembrie 2025 20:16:58
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.27 kb
#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;
}