Cod sursa(job #2924033)

Utilizator lolismekAlex Jerpelea lolismek Data 23 septembrie 2022 15:06:14
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define pii pair <int, int>

using namespace std;

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

const int N = 15000, LOG = 15, inf = 1e9;
int n, m, q;

struct Edge{
    int a, b, c;
};

bool cmp(Edge a, Edge b){
    return a.c < b.c;
}

vector <pii> adj[N + 1];
vector <Edge> edges;

int root[N + 1];

int Find(int nod){
    if(root[nod] == nod)
        return nod;
    return (root[nod] = Find(root[nod]));
}

void Union(int nod1, int nod2){
    int r1 = Find(nod1), r2 = Find(nod2);
    if(r1 != r2)
        root[r1] = r2;
}

void MST(){
    sort(edges.begin(), edges.end(), cmp);

    for(int i = 1; i <= n; i++)
        root[i] = i;

    vector <pii> aux[N + 1];
    for(auto e : edges){
        int r1 = Find(e.a), r2 = Find(e.b);

        if(r1 != r2){
            aux[e.a].push_back({e.b, e.c});
            aux[e.b].push_back({e.a, e.c});
            Union(e.a, e.b);
        }
    }

    for(int i = 1; i <= n; i++)
        adj[i] = aux[i];
}

int rmq1[N + 1][LOG + 1], lvl[N + 1];

void DFS1(int nod, int parent){
    lvl[nod] = lvl[parent] + 1;
    rmq1[nod][0] = parent;
    for(auto child : adj[nod])
        if(child.first != parent)
            DFS1(child.first, nod);
}

void buildLCA(){
    DFS1(1, 0);

    for(int j = 1; (1 << j) <= n; j++)
        for(int i = 1; i <= n; i++)
            rmq1[i][j] = rmq1[rmq1[i][j - 1]][j - 1];
}

int LCA(int a, int b){
    if(lvl[a] < lvl[b])
        swap(a, b);

    int dif = lvl[a] - lvl[b];
    for(int i = LOG - 1; i >= 0; i--)
        if(dif & (1 << i))
            a = rmq1[a][i];

    if(a == b)
        return a;

    for(int i = LOG - 1; i >= 0; i--)
        if(rmq1[a][i] != rmq1[b][i])
            a = rmq1[a][i], b = rmq1[b][i];

    return rmq1[a][0];
}

int ds[N + 1][LOG + 1], lg[N + 1];

void DFS2(int nod, int parent){
    for(auto child : adj[nod])
        if(child.first != parent)
            ds[child.first][0] = child.second, DFS2(child.first, nod);
}

void buildDS(){
    DFS2(1, 0);
    for(int i = 2; i <= N; i++)
        lg[i] = lg[i / 2] + 1;
    for(int j = 1; (1 << j) <= n; j++)
        for(int i = 1; i <= n; i++)
            ds[i][j] = max(ds[i][j - 1], ds[rmq1[i][j - 1]][j - 1]);
}

int queryDS(int nodD, int len){



    int ans = 0;
    for(int i = LOG - 1; i >= 0; i--)
        if(len & (1 << i))
            ans = max(ans, ds[nodD][i]), nodD = rmq1[nodD][i];
    return ans;
}

int main(){

    fin >> n >> m >> q;

    for(int i = 1; i <= m; i++){
        int a, b, c;
        fin >> a >> b >> c;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c});
        edges.push_back({a, b, c});
    }

    MST();
    buildLCA();
    buildDS();

    while(q--){
        int a, b;
        fin >> a >> b;

        int lca = LCA(a, b);
        fout << max(queryDS(a, lvl[a] - lvl[lca]), queryDS(b, lvl[b] - lvl[lca])) << '\n';
    }

    return 0;
}