Cod sursa(job #2400232)

Utilizator lupulescu2001Lupulescu Vlad lupulescu2001 Data 8 aprilie 2019 15:27:30
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

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

const int nMax = 15000;
const int mMax = 30000;
int n, m, k;
int tt[nMax + 5], use[nMax + 5], ad[nMax + 5];
vector<pair<int, int>> g[nMax + 5];
int dim, first[nMax + 5], eul[2 * nMax + 5], lvl[2 * nMax + 5];
int rmq[16][2 * nMax + 5];
int radacina;
int cost[2 * nMax + 5];
int sus[nMax + 5];
struct muchie {
    int x, y, c;
} v[mMax + 5];

bool comparator (muchie a, muchie b) {
    return a.c < b.c;
}

int Radacina(int x) {
    while(tt[x])
        x = tt[x];
    return x;
}

void DFS(int nod, int lev,int cst) {
    eul[++dim] = nod;
    first[nod] = dim;
    cost[nod] = cst;
    lvl[dim] = lev;
    for (auto i : g[nod]) {
        DFS(i.first, lev + 1, i.second);
        eul[++dim] = nod;
        lvl[dim] = lev;
        sus[i.first] = nod;
    }
}

void RMQ() {
    for (int i = 1; i <= dim; i++)
        rmq[0][i] = i;
    for (int i = 1; (1 << i) < dim; i++)
        for (int j = 1; j <= dim - (1 << i); j++) {
            rmq[i][j] = rmq[i - 1][j];
            int p = 1 << (i - 1);
            if (lvl[rmq[i][j]] > lvl[rmq[i - 1][j + p]])
                rmq[i][j] = rmq[i - 1][j + p];
        }
}

int LCA(int x, int y) {
    int a = first[x], b = first[y];
    if (a > b)
        swap(a, b);
    int dif = b - a + 1;
    int lg = log2(dif);
    int sol = rmq[lg][a];
    if (lvl[sol] > lvl[rmq[lg][a + dif - (1 << lg)]])
        sol = rmq[lg][a + dif - (1 << lg)];
    return eul[sol];
}

void Unire(muchie a) {
    if (use[a.x] == 0 && use[a.y] == 0) {
        tt[a.x] = a.y;
        g[a.y].push_back({a.x, a.c});
        ad[a.x] = 1;
        use[a.x] = 1;
        use[a.y] = 1;
    } else if (use[a.x] == 0) {
            int rad = Radacina(a.y);
            tt[a.x] = rad;
            g[a.y].push_back({a.x, a.c});
            use[a.x] = 1;
        } else if (use[a.y] == 0) {
                int rad = Radacina(a.x);
                tt[a.y] = rad;
                g[a.x].push_back({a.y, a.c});
                use[a.y] = 1;
            } else {
                int x = Radacina(a.x), y = Radacina(a.y);
                if (x == y)
                    return;
                if (ad[x] > ad[y]) {
                    tt[y] = x;
                    g[a.x].push_back({a.y, a.c});
                } else {
                    tt[x] = y;
                    g[a.y].push_back({a.x, a.c});
                }
                if (ad[x] == ad[y])
                    ad[y]++;
            }
}

int main() {
    fin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        fin >> v[i].x >> v[i].y >> v[i].c;
    }
    sort(v + 1, v + 1 + m, comparator);
    for (int i = 1; i <= m; i++) {
        if (!use[v[i].x] || !use[v[i].y])
            Unire(v[i]);
    }
    for (int i = 1; i <= n; i++) {
        if (tt[i] == 0)
            radacina = i;
    }
    DFS(radacina, 0, 0);
    RMQ();
    for (int i = 1; i <= k; i++) {
        int x, y;
        fin >> x >> y;
        int smth = LCA(x, y), sol = 0;
        while (x != smth) {
            sol = max(sol, cost[x]);
            x = sus[x];
        }
        while (y != smth) {
            sol = max(sol, cost[y]);
            y = sus[y];
        }
        fout << sol << '\n';
    }
}