Cod sursa(job #3030748)

Utilizator domistnSatnoianu Dominic Ioan domistn Data 17 martie 2023 20:47:24
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.86 kb
#include <bits/stdc++.h>

#define int long long

using namespace std;

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

typedef long long ll;
typedef pair<int, int> pii;

const int NMAX = 15000, MMAX = 30000, LOGNMAX = 15;

struct muc {
    int x, y, cost;
} muchii[MMAX + 1];

int n, m, k, dsu[NMAX + 1],
    niv[NMAX + 1],
    maxMuc[NMAX + 1][LOGNMAX + 1], upAPM[NMAX + 1][LOGNMAX + 1],
    pozLCA[NMAX + 1], sparseLCA[2 * NMAX + 1][LOGNMAX + 1], etl,
    lg2[2 * NMAX + 1];
vector<pii> adj[NMAX + 1];
vector<int> eulerTour;

inline int findRadac(int x) {
    int radac = x;
    while(radac != dsu[radac]) radac = dsu[radac];
    while(x != dsu[x]) {
        int crt = dsu[x];
        dsu[x] = radac;
        x = crt;
    }
    return radac;
}

void dfsGener(int nod, int tata = -1, int lnMuc = 0) {
    if(nod != 1) {
        niv[nod] = niv[tata] + 1;
        maxMuc[nod][0] = lnMuc;
        upAPM[nod][0] = tata;
        for(int i = 1; (1 << i) <= niv[nod]; ++i) {
            upAPM[nod][i] = upAPM[upAPM[nod][i - 1]][i - 1];
            maxMuc[nod][i] = max(maxMuc[nod][i - 1],
                                 maxMuc[upAPM[nod][i - 1]][i - 1]);
        }
    }
    for(const auto &el : adj[nod]) {
        if(el.first == tata) continue;
        dfsGener(el.first, nod, el.second);
    }
}

void dfsEulerTour(int nod, int tata = -1) {
    pozLCA[nod] = eulerTour.size();
    eulerTour.push_back(nod);
    for(const auto &el : adj[nod]) {
        if(el.first == tata) continue;
        dfsEulerTour(el.first, nod);
        eulerTour.push_back(nod);
    }
}

void generLCA() {
    lg2[1] = 0;
    for(int i = 2; i <= 2 * NMAX; ++i)
        lg2[i] = lg2[i / 2] + 1;
    for(int i = 1; i <= etl; ++i)
        sparseLCA[i][0] = eulerTour[i];
    for(int sz = 1; (1 << sz) <= etl; ++sz)
        for(int i = 1; i + (1 << sz) - 1 <= etl; ++i) {
            const int v1 = sparseLCA[i][sz - 1],
                      v2 = sparseLCA[i + (1 << (sz - 1))][sz - 1];
            if(niv[v1] < niv[v2]) sparseLCA[i][sz] = v1;
            else sparseLCA[i][sz] = v2;
        }
}

inline int lca(int x, int y) {
    x = pozLCA[x];
    y = pozLCA[y];
    if(x > y) swap(x, y);
    const int lg2dist = lg2[y - x + 1],
              v1 = sparseLCA[x][lg2dist],
              v2 = sparseLCA[y - (1 << lg2dist) + 1][lg2dist];
    if(niv[v1] < niv[v2]) return v1;
    return v2;
}

int32_t main()
{
    fin >> n >> m >> k;
    for(int i = 1; i <= n; ++i)
        dsu[i] = i;
    for(int i = 1; i <= m; ++i)
        fin >> muchii[i].x >> muchii[i].y >> muchii[i].cost;
    sort(muchii + 1, muchii + m + 1, [](const muc A, const muc B) {
         return A.cost < B.cost;
    });
    for(int i = 1; i <= m; ++i) {
        int rx = findRadac(muchii[i].x), ry = findRadac(muchii[i].y);
        if(rx != ry) {
            dsu[rx] = ry;
            adj[muchii[i].x].push_back({muchii[i].y, muchii[i].cost});
            adj[muchii[i].y].push_back({muchii[i].x, muchii[i].cost});
        }
    }
    dfsGener(1);

//    for(int i = 1; i <= n; ++i) {
//        cout << i << ": ";
//        for(const auto &el : adj[i]) cout << el.first << " (" << el.second << ")  ";
//        cout << "\n";
//    }
//    for(int i = 1; i <= n; ++i) {
//        cout << i << " (niv " << niv[i] << ")" << ":\n";
//        for(int j = 1, logj = 0; j <= niv[i]; j *= 2, ++logj) {
//            cout << "\t2^" << logj << " = " << j << ": " << upAPM[i][logj] << "\n";
//        }
//    }

    eulerTour.push_back(0);
    dfsEulerTour(1);
    etl = eulerTour.size() - 1;
//    for(const auto &el : eulerTour) cout << el << " ";
    generLCA();

    for(int i = 1, x, y; i <= k; ++i) {
        fin >> x >> y;
        int lcaxy = lca(x, y);
        int lg2distx = lg2[niv[x] - niv[lcaxy]],
            lg2disty = lg2[niv[y] - niv[lcaxy]];
        int nx = x, ny = y;
        for(int b = 0; (1 << (b + 1)) < niv[x] - niv[lcaxy]; ++b)
            if((1 << b) & lg2distx) nx = upAPM[nx][b];
        for(int b = 0; (1 << (b + 1)) < niv[y] - niv[lcaxy]; ++b)
            if((1 << b) & lg2disty) ny = upAPM[ny][b];

//        cout << x << " " << y << ":\n";
//        cout << "\tLCA:" << lcaxy << "\n";
//        cout << "\tDist log2 x:" << lg2distx << "\n";
//        cout << "\tnx:" << nx << "\n";
//        cout << "\tDist log2 y:" << lg2disty << "\n";
//        cout << "\tny:" << ny << "\n\n";
//        cout << "\t" << maxMuc[x][lg2distx] << "\n";
//        cout << "\t" << maxMuc[nx][lg2distx] << "\n";
//        cout << "\t" << maxMuc[y][lg2disty] << "\n";
//        cout << "\t" << maxMuc[ny][lg2disty] << "\n";

        int ans = 0;
        if(x != lcaxy) ans = max({ans, maxMuc[x][lg2distx], maxMuc[nx][lg2distx]});
        if(y != lcaxy) ans = max({ans, maxMuc[y][lg2disty], maxMuc[ny][lg2disty]});
        cout << ans << "\n";
    }
    return 0;
}