Cod sursa(job #2400201)

Utilizator lupulescu2001Lupulescu Vlad lupulescu2001 Data 8 aprilie 2019 14:37:58
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.11 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];
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[dim] = cst;
    lvl[dim] = lev;
    for (auto i : g[nod]) {
        DFS(i.first, lev + 1, i.second);
        eul[++dim] = nod;
        lvl[dim] = lev;
        cost[dim] = cst;
    }
}

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) + 1; j++) {
            rmq[i][j] = rmq[i - 1][j];
            int p = 1 << (i - 1);
            if (cost[rmq[i][j]] < cost[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 (cost[sol] < cost[rmq[lg][a + dif - (1 << lg)]])
        sol = rmq[lg][a + dif - (1 << lg)];
    return cost[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;
        fout << LCA(x, y) << '\n';
    }
}