Cod sursa(job #2779631)

Utilizator cyg_dawidDavid Ghiberdic cyg_dawid Data 4 octombrie 2021 15:12:43
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <fstream>
#include <algorithm>
#include <climits>
#include <vector>

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

struct EDGE {
    int nod1, nod2;
    int cost;
    bool operator < (EDGE other) const {
        return cost < other.cost;
    }
};
std::vector <EDGE> edges;
std::vector <EDGE> apm;
std::vector <std::vector <std::pair <int, int>>> adjacency;

int const nmax = 15000;
struct DSU {
    int p[nmax + 5], r[nmax + 5];
    void init (int n) {
        for (int i = 1; i <= n; i++) {
            p[i] = i;
            r[i] = 0;
        }
    }
    int find (int x) {
        if (p[x] == x) return x;
        return p[x] = find (p[x]);
    }
    void unite (int x, int y) {
        x = find (x);
        y = find (y);
        if (r[x] < r[y])
            std::swap (x, y);
        p[y] = x;
        if (r[x] == r[y])
            r[x]++;
    }
} UnionFind;

void build_apm (int n, int m) {
    UnionFind.init (n);
    std::sort (edges.begin(), edges.end());
    for (int i = 0; i < m; i++) {
        if (UnionFind.find (edges[i].nod1) != UnionFind.find (edges[i].nod2)) {
            UnionFind.unite (edges[i].nod1, edges[i].nod2);
            apm.push_back(edges[i]);
            adjacency[edges[i].nod1].push_back({edges[i].nod2, edges[i].cost});
            adjacency[edges[i].nod2].push_back({edges[i].nod1, edges[i].cost});
        }
    }
}

int const pmax = 15;
bool seen[nmax + 5];
int level[nmax + 5];
int stramosi[pmax][nmax + 5];
int maxPeStramosi[pmax][nmax + 5];

void dfs (int nod) {
    seen[nod] = true;
    int lim = adjacency[nod].size();
    for (int i = 0; i < lim; i++) {
        if (!seen[adjacency[nod][i].first]) {
            stramosi[0][adjacency[nod][i].first] = nod;
            maxPeStramosi[0][adjacency[nod][i].first] = adjacency[nod][i].second;
            level[adjacency[nod][i].first] = level[nod] + 1;
            dfs (adjacency[nod][i].first);
        }
    }
}
void build_stramosi (int n) {
    // construim layer-ul 1 de stramosi
    dfs (1);
    int logLim = log2 (n);
    for (int p = 1; p <= logLim; p++) {
        for (int i = 1; i <= n; i++) {
            stramosi[p][i] = stramosi[p - 1][stramosi[p - 1][i]];
            maxPeStramosi[p][i] = std::max (maxPeStramosi[p - 1][i], maxPeStramosi[p - 1][stramosi[p - 1][i]]);
        }
    }
}

int main() {
    int n, m, k;
    fin >> n >> m >> k;
    adjacency.resize (n + 1);
    for (int i = 1; i <= m; i++) {
        int x, y, c;
        fin >> x >> y >> c;
        edges.push_back({x, y, c});
    }
    build_apm (n, m);
    build_stramosi (n);
    level[0] = INT_MIN;
    for (int i = 1; i <= k; i++) {
        int x, y, mmax = INT_MIN;
        fin >> x >> y;
        if (level[x] < level[y])
            std::swap (x, y);
        if (level[x] != level[y]) {
            int logLim = log2 (n);
            for (int p = logLim; p >= 0; p--) {
                if (level[stramosi[p][x]] > level[y]) {
                    mmax = std::max (mmax, maxPeStramosi[p][x]);
                    x = stramosi[p][x];
                }
            }
            mmax = std::max (mmax, maxPeStramosi[0][x]);
            x = stramosi[0][x];
        }
        if (x == y) {
            fout << mmax << "\n";
            continue;
        }
        int logLim = log2 (n);
        for (int p = logLim; p >= 0; p--) {
            if (stramosi[p][x] != stramosi[p][y]) {
                mmax = std::max (mmax, maxPeStramosi[p][x]);
                mmax = std::max (mmax, maxPeStramosi[p][y]);
                x = stramosi[p][x];
                y = stramosi[p][y];
            }
        }
        mmax = std::max (mmax, maxPeStramosi[0][x]);
        mmax = std::max (mmax, maxPeStramosi[0][y]);
        fout << mmax << "\n";
    }
    return 0;
}