Cod sursa(job #3253602)

Utilizator vladm98Munteanu Vlad vladm98 Data 3 noiembrie 2024 19:16:26
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>

using namespace std;

int tata[100005], height[100005];

vector <pair <int, pair <int, int>>> edges;
set <int> queries[100005];
int answer[100005];

int stapan (int nod)
{
    int rege = nod, copie;
    while (tata[rege] != rege)
        rege = tata[rege];
    while (tata[nod] != nod)
    {
        copie = nod;
        nod = tata[nod];
        tata[copie] = rege;
    }
    return rege;
}
void unire (int a, int b)
{
    int st1 = stapan(a), st2 = stapan(b);
    if (st2 == st1)
        return ;
    if (height[st1] > height[st2])
        tata[st2] = st1;
    else
        tata[st1] = st2;
    if (height[st1] == height[st2])
        height[st2]++;
}

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<=n; ++i)
    {
        tata[i] = i;
        height[i] = 1;
    }
    for (int i = 1; i <= m; ++i) {
        int x, y, cost;
        cin >> x >> y >> cost;
        edges.push_back({cost, {x, y}});
    }
    for (int i = 1; i <= k; ++i) {
        int x, y;
        cin >> x >> y;
        queries[x].insert(i);
        queries[y].insert(i);
    }
    sort(edges.begin(), edges.end());

    for (auto edge : edges) {
        if (stapan(edge.second.first) == stapan(edge.second.second)) continue;
        // Queryurile unei componente trebuie sa se afle mereu in setul radacinii acelei componente
        int leftRoot = stapan(edge.second.first);
        int rightRoot = stapan(edge.second.second);
        // Fortam rightRoot sa aiba setul cu sizeul mai mic
        if (queries[leftRoot].size() < queries[rightRoot].size()) {
            swap(leftRoot, rightRoot);
        }

        vector <int> toDelete;

        // iteram prin setul mai mic si incercam sa vedem la ce query uri putem raspunde
        for (auto query : queries[rightRoot]) {
            if (queries[leftRoot].find(query) != queries[leftRoot].end()) {
                answer[query] = edge.first;
                toDelete.emplace_back(query);
            }
        }

        // sterg din seturi queryurile rezolvate
        for (auto toDel : toDelete) {
            queries[leftRoot].erase(toDel);
            queries[rightRoot].erase(toDel);
        }

        // combin query urile
        for (auto query : queries[rightRoot]) {
            queries[leftRoot].insert(query);
        }

        unire(leftRoot, rightRoot);

        // Daca leftRoot nu este de fapt radacina, atunci trebuie sa imi mut set ul in rightRoot
        if (leftRoot != stapan(leftRoot)) {
            swap(queries[leftRoot], queries[rightRoot]); // O(1)
        }
    }

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