Cod sursa(job #3129515)

Utilizator preda.andreiPreda Andrei preda.andrei Data 14 mai 2023 20:47:34
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <algorithm>
#include <fstream>
#include <tuple>
#include <vector>

using namespace std;

struct DisjointSet {
    vector<int> parent;
    vector<int> depth;
    vector<int> cost;

    DisjointSet(int nodes)
        : parent(nodes, -1), depth(nodes, 1), cost(nodes, 0) {
    }

    bool Unite(int a, int b, int ab_cost) {
        auto root_a = Root(a);
        auto root_b = Root(b);
        if (root_a == root_b) {
            return false;
        }

        if (depth[root_a] < depth[root_b]) {
            swap(root_a, root_b);
        }
        parent[root_b] = root_a;
        depth[root_a] = max(depth[root_a], depth[root_b] + 1);
        cost[root_b] = ab_cost;

        return true;
    }

    int Root(int node) {
        while (parent[node] != -1) {
            node = parent[node];
        }
        return node;
    }
};

struct Node {
    int depth;
    int parent;
    int cost;
};

using Tree = vector<Node>;

using Edge = tuple<int, int, int>;

void FindDepth(Tree& tree, int node) {
    if (tree[node].depth != -1) {
        return;
    }
    if (tree[node].parent == -1) {
        tree[node].depth = 0;
        return;
    }

    auto parent = tree[node].parent;
    FindDepth(tree, parent);
    tree[node].depth = tree[parent].depth + 1;
}

Tree FindMst(int nodes, vector<Edge>& edges) {
    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {
        return get<2>(a) < get<2>(b);
    });

    auto dset = DisjointSet(nodes);
    for (const auto& [a, b, cost] : edges) {
        dset.Unite(a, b, cost);
    }

    auto tree = Tree(nodes);
    for (int i = 0; i < nodes; i += 1) {
        tree[i].depth = -1;
        tree[i].parent = dset.parent[i];
        tree[i].cost = dset.cost[i];
    }
    for (int i = 0; i < nodes; i += 1) {
        if (tree[i].depth == -1) {
            FindDepth(tree, i);
        }
    }
    return tree;
}

int Solve(const Tree& tree, int a, int b) {
    int res = 0;
    while (a != b) {
        auto& to_move = tree[a].depth < tree[b].depth ? b : a;
        res = max(res, tree[to_move].cost);
        to_move = tree[to_move].parent;
    }
    return res;
}

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

    int nodes, edges, queries;
    fin >> nodes >> edges >> queries;

    auto graph = vector<Edge>(edges);
    for (auto& [a, b, cost] : graph) {
        fin >> a >> b >> cost;
        a -= 1;
        b -= 1;
    }

    auto mst = FindMst(nodes, graph);
    for (int i = 0; i < queries; i += 1) {
        int a, b;
        fin >> a >> b;

        auto res = Solve(mst, a - 1, b - 1);
        fout << res << "\n";
    }
    return 0;
}