Cod sursa(job #3342441)

Utilizator MegaCoderMinoiu Teodor Mihai MegaCoder Data 24 februarie 2026 11:18:51
Problema Radiatie Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include<fstream>
#include<vector>
#include<bitset>
#include<algorithm>
#define pii std::pair<int, int>

std::ifstream fin("radiatie.in");
std::ofstream fout("radiatie.out");

const int NMAX=15001;
const int LGMAX=22;

std::vector<pii>mst[NMAX];
std::vector<std::pair<int, pii>>edges;
std::vector<int>t(NMAX), cnt(NMAX, 1);
std::vector<int>tin(NMAX), tout(NMAX);

pii lmax[NMAX][LGMAX];//max and ancestor

int n, m, q;
inline int root(int x)
{
    if(!t[x])
        return x;
    t[x]=root(t[x]);
    return t[x];
}
inline void unite(int x, int y, int cost)
{
    int rx=root(x), ry=root(y);
    if(rx==ry)
        return;
    mst[x].emplace_back(y, cost);
    mst[y].emplace_back(x, cost);
    if(cnt[rx]>cnt[ry])
    {
        t[ry]=rx;
        cnt[rx]+=cnt[ry];
        return;
    }
    t[rx]=ry;
    cnt[ry]+=cnt[rx];
}
void read()
{
    fin>>n>>m>>q;
    for(int i=0; i<m; ++i)
    {
        int from, to, cost;
        fin>>from>>to>>cost;
        edges.push_back({cost, {from, to}});
    }
}
void kruskal()
{
    std::sort(edges.begin(), edges.end());
    for(auto it:edges)
    {
        int from=it.second.first, to=it.second.second, cost=it.first;
        unite(from, to, cost);
    }
}
void dfs(int node, int parent, int cost, int &time)
{
    lmax[node][0]={parent, cost};
    int d=0;
    while(lmax[lmax[node][d].first][d].first)
    {
        pii upper=lmax[lmax[node][d].first][d];
        lmax[node][d+1]={upper.first, std::max(upper.second, lmax[node][d].second)};
        ++d;
    }
    tin[node]=++time;
    for(auto it:mst[node])
    {
        if(it.first==parent)continue;
        dfs(it.first, node, it.second, time);
    }
    tout[node]=++time;
}
inline bool isAnc(int cand, int node)//cand is anc of node
{
    return tin[cand]<tin[node] && tout[cand]>tout[node];
}
inline int query(int a, int b)
{
    int ans=0;

    if(isAnc(b, a))
        std::swap(a, b);
    else if(!isAnc(a, b))
    {
        for(int d=19; d; --d)
        {
            int upper=lmax[a][d].first, cost=lmax[a][d].second;
            if(upper && !isAnc(upper, b))
            {
                a=upper;
                ans=std::max(ans, cost);
            }
        }
        ans=std::max(ans, lmax[a][0].second);
        a=lmax[a][0].first;//ancestor
    }

    for(int d=19; d; --d)
    {
        int upper=lmax[b][d].first, cost=lmax[b][d].second;
        if(upper && !isAnc(upper, a))
        {
            b=upper;
            ans=std::max(ans, cost);
        }
    }
    if(a!=b)
        ans=std::max(ans, lmax[b][0].second);
    return ans;
}
void solve()
{
    kruskal();

    int time=0;
    dfs(1, 0, 0, time);

    while(q--)
    {
        int a, b;
        fin>>a>>b;
        fout<<query(a, b)<<'\n';
    }
}
int main()
{
    read();
    solve();
    return 0;
}