Cod sursa(job #1693511)

Utilizator sucureiSucureiRobert sucurei Data 23 aprilie 2016 11:50:18
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.16 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

struct Edge{

    int x, y, cost;

    Edge(int x, int y, int cost) {
        this->x = x;
        this->y = y;
        this->cost = cost;
    }

    bool operator < (const Edge a) const {
        return cost < a.cost;
    }

};

vector<Edge> edges;
vector< vector< pair<int, int> > > graph;
vector<int> pmd, parent, costParent, level;
vector< vector<int> > ancestors, ancestorsCost;

int getRoot(int node) {

    int temp = node;
    while (pmd[node] > 0)
        node = pmd[node];

    swap(temp, node);

    while (node != temp) {
        pmd[node] = temp;
        node = pmd[node];
    }

    return temp;

}

void kruskal(vector<Edge> edges, int n, vector< vector< pair<int, int> > > &graph) {

    sort(edges.begin(), edges.end());

    pmd.clear();
    pmd.resize(n + 1, -1);

    for (unsigned int i = 0; i < edges.size(); ++i) {

        int x = edges[i].x;
        int y = edges[i].y;
        int cost = edges[i].cost;

        int rx = getRoot(x);
        int ry = getRoot(y);

        if (rx == ry)
            continue;

        if (pmd[rx] < pmd[ry]) {

            pmd[rx] += pmd[ry];
            pmd[ry] = rx;

        }
        else {

            pmd[ry] += pmd[rx];
            pmd[rx] = ry;

        }

        graph[x].push_back(make_pair(y, cost));
        graph[y].push_back(make_pair(x, cost));

    }

}

void dfs(int node, int par, int costPar, int lvl) {

    parent[node] = par;
    costParent[node] = costPar;
    level[node] = lvl;

    for (unsigned int i = 0; i < graph[node].size(); ++i) {

        int adj = graph[node][i].first;
        int cost = graph[node][i].second;

        if (adj == par)
            continue;

        dfs(adj, node, cost, lvl + 1);

    }

}

void compAncestors(int n, vector< vector<int> > &ancestors, vector< vector<int> > &ancestorsCost) {

    for (int i = 1; i <= n; ++i) {

        ancestors[0][i] = parent[i];
        ancestorsCost[0][i] = costParent[i];

    }
    for (int i = 1; (1 << i) <= n; ++i) {

        for (int j = 1; j <= n; ++j) {

            ancestors[i][j] = ancestors[i - 1][ancestors[i - 1][j]];
            ancestorsCost[i][j] = max(ancestorsCost[i - 1][ancestors[i - 1][j]], ancestorsCost[i - 1][j]);

        }

    }

}

int goUp(int &node, int lvl) {

    int ret = 0;
    for (int i = 16; i >= 0; --i) {

        if (level[node] - lvl >= (1 << i)) {

            ret = max(ret, ancestorsCost[i][node]);
            node = ancestors[i][node];

        }

    }

    return ret;

}

int query(int x, int y) {

    int ret = 0;
    for (int i = 16; i >= 0; --i) {

        if (ancestors[i][x] != ancestors[i][y]) {

            ret = max(ret, ancestorsCost[i][x]);
            ret = max(ret, ancestorsCost[i][y]);

            x = ancestors[i][x];
            y = ancestors[i][y];

        }

    }

    if (x != y) {
        ret = max(ret, ancestorsCost[0][x]);
        ret = max(ret, ancestorsCost[0][y]);
    }

    return ret;

}

int main() {

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

    int n, k, m;
    fin >> n >> m >> k;

    graph.resize(n + 1);

    for (int i = 1; i <= m; ++i) {

        int x, y, cost;
        fin >> x >> y >> cost;

        edges.push_back(Edge(x, y, cost));

    }

    kruskal(edges, n, graph);

    parent.resize(n + 1, 0);
    costParent.resize(n + 1, 0);
    level.resize(n + 1, 0);
    for (int i = 1; i <= n; ++i)
        if (level[i] == 0)
            dfs(i, 0, 0, 1);

    ancestors.resize(17, vector<int>(n + 1, 0));
    ancestorsCost.resize(17, vector<int>(n + 1, 0));
    compAncestors(n, ancestors, ancestorsCost);

    for (; k; --k) {

        int x, y;
        fin >> x >> y;

        int ans = 0;

        if (level[x] > level[y])
            ans = goUp(x, level[y]);
        else if (level[x] < level[y])
            ans = goUp(y, level[x]);

        ans = max(ans, query(x, y));

        fout << ans << '\n';

    }

    return 0;

}

//Trust me, I'm the Doctor!