Cod sursa(job #1331958)

Utilizator andreiblaj17Andrei Blaj andreiblaj17 Data 1 februarie 2015 14:16:48
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.66 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#define nmax 15005

using namespace std;

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

struct muchie {
    int x, y, cost;
} M[2*nmax];

int n, m, k, q = 0;
vector < pair<int, int> > V[nmax];

void citire() {
    int a, b, c;
    fin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        fin >> a >> b >> c;
        M[i].x = a;
        M[i].y = b;
        M[i].cost = c;
    }
}

int R[nmax], NR[nmax];

bool cmp(muchie a, muchie b) {
    return a.cost < b.cost;
}

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

void kruskal() {
    int i;
    for (i = 1; i <= n; i++)
        NR[i] = 1, R[i] = i;
    int nrm = 0;
    sort(M+1,M+m+1,cmp);
    for (i = 1; i <= m; i++) {
        int p1 = root(M[i].x);
        int p2 = root(M[i].y);
        if (p1 == p2)
            continue;
        if (NR[p1] >= NR[p2]) {
            NR[p1] += NR[p2];
            R[p2] = p1;
        } else {
            NR[p2] += NR[p1];
            R[p1] = p2;
        }
        nrm++;
        V[M[i].x].push_back(make_pair(M[i].y, M[i].cost));
        V[M[i].y].push_back(make_pair(M[i].x, M[i].cost));
        if (nrm == n-1)
            break;
    }
}

int e;
bool viz[nmax];
int P[nmax], Exp[2*nmax], Poz[18][2*nmax], Nivel[nmax], Min[18][nmax], E[nmax], Max[17][2*nmax], tata[17][nmax];

void euler(int nod, int niv) {
    viz[nod] = true;
    E[++E[0]] = nod;
    Nivel[nod] = niv;
    P[nod] = E[0];
    for (int i = 0; i < V[nod].size(); i++)
        if (!viz[V[nod][i].first]) {
            Max[0][V[nod][i].first] = V[nod][i].second;
            tata[0][V[nod][i].first] = nod;
            euler(V[nod][i].first, niv+1);
            E[++E[0]] = nod;
        }
}

void preprocess1() {
    for (int i = 1; i <= E[0]; i++)
        Min[0][i] = Nivel[E[i]],
        Poz[0][i] = i;
    Exp[1] = 0;
    for (int i = 2; i <= E[0]; i++)
        Exp[i] = Exp[i/2] + 1;
    for (int i = 1; i <= Exp[E[0]]; i++)
        for (int j = 1; j <= E[0] - (1<<i) + 1; j++) {
            int dr = j + (1<<i) - 1;
            int mid = dr - (1<<(i-1)) + 1;
            Min[i][j] = Min[i-1][j];
            Poz[i][j] = Poz[i-1][j];
            if (Min[i][j] > Min[i-1][mid]) {
                Min[i][j] = Min[i-1][mid];
                Poz[i][j] = Poz[i-1][mid];
            }
        }
}

void preprocess2() {
    for (int i = 1; i <= Exp[n]; i++)
        for (int j = 1; j <= n; j++) {
            int x = tata[i-1][j];
            Max[i][j] = max(Max[i-1][j], Max[i-1][x]);
            tata[i][j] = tata[i-1][x];
        }
}

int Muchie(int lca, int nod) {
    int k = Nivel[nod] - Nivel[lca];
    int rez = 0;
    for (int i = 14; i >= 0; i--)
        if ((k & (1<<i)) != 0) {
            rez = max(rez, Max[i][nod]);
            nod = tata[i][nod];
        }
    return rez;
}

void solve() {
    euler(1, 1);
    preprocess1();
    preprocess2();
    for (int i = 1; i <= k; i++) {
        int x, y;
        fin >> x >> y;
        
        int xi = P[x];
        int yi = P[y];
        
        if (xi > yi) swap(xi, yi);
        
        int l = yi - xi + 1;
        int k = Exp[l];
        
        int rez = Min[k][xi];
        int lca = E[Poz[k][xi]];
        
        int PozL = Poz[k][xi];
        
        xi = yi - (1<<k) + 1;
        
        if (Min[k][x] < rez)
            lca = E[Poz[k][xi]],
            PozL = Poz[k][xi];
    
        rez = 0;
        
        rez = max(rez, Muchie(lca, x));
        rez = max(rez, Muchie(lca, y));
        
        fout << rez << "\n";
        
    }
}

int main() {
    
    citire();
    kruskal();
    solve();
    
    fin.close();
    fout.close();
    
    return 0;
}