Cod sursa(job #3255273)

Utilizator vladm98Munteanu Vlad vladm98 Data 9 noiembrie 2024 22:07:04
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <bits/stdc++.h>

using namespace std;

int father[100005], ranks[100005], answers[100005];

int getRoot(int node) {
    int root = node;
    while (root != father[root]) {
        root = father[root];
    }
    while (root != node) {
        int parent = father[node];
        father[node] = root;
        node = parent;
    }
    return root;
}

void join(int nodeLeft, int nodeRight) {
    int rootLeft = getRoot(nodeLeft);
    int rootRight = getRoot(nodeRight);

    if (rootLeft == rootRight) return ;
    if (ranks[rootLeft] < ranks[rootRight]) swap(rootLeft, rootRight);
    if (ranks[rootLeft] == ranks[rootRight]) ranks[rootLeft] += 1;
    father[rootRight] = rootLeft;
}

vector <pair <int, pair <int, int>>> edges;
vector <pair <pair <int, int>, pair <int, int>>> queries;

vector <pair <pair <int, int>, pair <int, int>>> joinArrays(vector <pair <pair <int, int>, pair <int, int>>> A, vector <pair <pair <int, int>, pair <int, int>>> B) {
    vector <pair <pair <int, int>, pair <int, int>>> result;
    int aIndex = 0, bIndex = 0;
    for (int i = 0; i < A.size() + B.size(); ++i) {
        if (aIndex == A.size() or (bIndex < B.size() and A[aIndex].first.first > B[bIndex].first.first)) {
            result.push_back(B[bIndex]);
            bIndex += 1;
        } else {
            result.push_back(A[aIndex]);
            aIndex += 1;
        }
    }

    return result;
}

void pushBinarySearchPower(int power, int n) {
    for (int i = 1; i <= n; ++i) {
        ranks[i] = 1;
        father[i] = i;
    }
    vector <pair <pair <int, int>, pair <int, int>>> goodQueries, badQueries;
    int edgeIndex = 0;

    for (auto query : queries) {
        while (edgeIndex < edges.size() and query.first.first + (1 << power) >= edges[edgeIndex].first) {
            join(edges[edgeIndex].second.first, edges[edgeIndex].second.second);
            edgeIndex += 1;
        }

        if (getRoot(query.second.first) != getRoot(query.second.second)) {
            query.first.first += (1 << power);
            goodQueries.push_back(query);
        } else {
            badQueries.push_back(query);
        }
    }

    queries = joinArrays(goodQueries, badQueries);
}


int main() {
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= m; ++i) {
        int x, y, cost;
        cin >> x >> y >> cost;
        edges.push_back({cost, {x, y}});
    }
    sort(edges.begin(), edges.end());
    for (int i = 1; i <= k; ++i) {
        int x, y;
        cin >> x >> y;
        queries.push_back({{-1, i}, {x, y}});
    }

    for (int i = 30; i >= 0; --i) {
        pushBinarySearchPower(i, n);
    }

    for (auto query : queries) answers[query.first.second] = query.first.first + 1;

    for (int i = 1; i <= k; ++i) {
        cout << answers[i] << '\n';
    }
    return 0;
}