Cod sursa(job #1657343)

Utilizator bogdanciurezubogdan ciurezu bogdanciurezu Data 20 martie 2016 13:34:45
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.57 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

ifstream f("radiatie.in");
ofstream g("radiatie.out");

const int nmax = 15050, nrComp = 100;

class cmp{

    public : bool operator()( pair<int, pair<int, int> > &x, pair<int, pair<int, int> > &y){
        return (x.second.first > y.second.first);
    };
};

vector < pair<int, int> > graf[nmax], apm[nmax], parcE[nrComp];
priority_queue < pair<int, pair<int, int> >, vector< pair<int, pair<int, int> > >, cmp > Q;

bool ver[nmax], ver2[nmax];

int n, m, k, firstAp[nmax], mat[20][nmax], dimParc[nrComp], logaritm[nmax], comp[nmax], nrCC;

void DFS(int nod){

    comp[nod] = nrCC;

    for(int i = 0; i < graf[nod].size(); ++i){
        if( !comp[ graf[nod][i].second ] )
            DFS( graf[nod][i].second );
    }
}

void arbPM(int nod){

    for(int i = 0; i < graf[nod].size(); ++i){
        Q.push( make_pair(nod, graf[nod][i] ) );
    }
    ver[nod] = true;

    pair <int, int> muchie;
    int cost, nodS, nodD;

    while( !Q.empty() ){

        nodS = ( Q.top() ).first;
        nodD = ( Q.top() ).second.second;
        cost = ( Q.top() ).second.first;
        Q.pop();

        if(!ver[nodD]){
            apm[nodS].push_back( make_pair(cost, nodD) );
            apm[nodD].push_back( make_pair(cost, nodS) );
            ver[nodD] = true;

            for(int i = 0; i < graf[nodD].size(); ++i){
                int sec = graf[nodD][i].second;
                    Q.push( make_pair(nodD, graf[nodD][i] ) );
            }
        }
    }

}

void parcurgereEuleriana(int nod){

    firstAp[nod] = parcE[nrCC].size();

    for(int i = 0; i < apm[nod].size(); ++i){

        if( !ver2[ apm[nod][i].second ] ){
            ver2[ apm[nod][i].second] = true;

            parcE[nrCC].push_back( make_pair(nod, apm[nod][i].first) );

            parcurgereEuleriana( apm[nod][i].second );
        }
    }
    parcE[nrCC].push_back( make_pair(nod, -1) );
}

void precRMQ(int com){
    for(int i = 0; i < dimParc[com]; ++i){
        mat[0][i] = parcE[com][i].second;
    }

    for(int i = 1; (1 << i) < dimParc[com]; ++i){
        for(int j = 0; j < dimParc[com] - (1 << i) + 1; ++j){
            int s = (1 << (i - 1) );
            mat[i][j] = max(mat[i - 1][j], mat[i - 1][j + s]);
        }
    }

    for(int i = 1; i <= dimParc[com]; ++i){
        logaritm[i] = logaritm[i >> 1] + 1;
    }
}

int RMQ(int x, int y){

    if(firstAp[x] > firstAp[y])
        swap(x, y);

    int dif = firstAp[y] - firstAp[x] - 1;

    //g<<logaritm[dif]<<':'<<firstAp[x]<<','<<firstAp[y] - ( 1 << logaritm[dif] ) + 1<<'\n';
    return max( mat[ logaritm[dif] ][ firstAp[x] ], mat[ logaritm[dif] ][ firstAp[y] - ( 1 << logaritm[dif] ) + 1 ] );


}

int main()
{
    f>>n>>m>>k;

    for(int i = 1, x, y, c; i <= n; ++i){
        f>>x>>y>>c;

        graf[x].push_back( make_pair(c, y) );
        graf[y].push_back( make_pair(c, x) );
    }

    for(int i = 1; i <= n; ++i){
        if(!comp[i]){
            ++nrCC;
            DFS(i);

            arbPM(i);
            ver2[i] = true;
            parcurgereEuleriana(i);
            dimParc[nrCC] = parcE[nrCC].size();
        }
    }
    int x, y, lastComp;

    f>>x>>y;
    lastComp = comp[x];

    precRMQ(lastComp);
    g<<RMQ(x, y)<<'\n';

    for(int i = 2; i <= k; ++i){
        f>>x>>y;
        if(comp[x] != lastComp){
            lastComp = comp[x];
            precRMQ(lastComp);
        }
        g<<RMQ(x, y)<<'\n';
    }
    return 0;
}