Cod sursa(job #1955420)

Utilizator AkrielAkriel Akriel Data 5 aprilie 2017 23:02:13
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.72 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N = 15005;
const int D = log2(3*N);

tuple <int, int, int> edges[2*N]; // cost, origin, destination

vector <pair <int, int> > nodes[N]; // destination, cost;

vector <pair <int, int> > eulerChart; // node, cost;

bitset <N> visited;

int totalNodes, totalEdges, totalQuestions;

int rangeMaximum[D][3*N];

int root[N], position[N], length[D];

int depth;

int getRoot(int node){
    if ( node == root[node])
        return node;
    root[node] = getRoot(root[node]);
    return root[node];
}

inline void readVariables(){
    fin >> totalNodes >> totalEdges >> totalQuestions;

    int origin, destination, cost;
    for ( int index = 1; index <= totalEdges; index++ ){
        fin >> origin >> destination >> cost;
        edges[index] = make_tuple(cost, origin, destination);
    }
}

inline void partialArbore(){
    sort(edges+1, edges+totalEdges+1);

    for ( int index = 1; index <= totalNodes; index++ )
        root[index] = index;

    for ( int index = 1; index <= totalEdges; index++ ){
        int cost, origin, destination;
        tie (cost, origin, destination) = edges[index];
        int rootOrigin = getRoot(origin),
            rootDestination = getRoot(destination);

        if ( rootOrigin != rootDestination ){
            root[rootOrigin] = root[rootDestination];
            nodes[origin].push_back({destination, cost});
            nodes[destination].push_back({origin, cost});
        }
    }
}

void deepFirstSearch(int node = 1, int cost = 0){
    visited[node] = true;
    eulerChart.push_back({node, cost});
    position[node] = eulerChart.size();

    for ( auto it : nodes[node]){
        if ( !visited[it.first] ){
            deepFirstSearch(it.first, it.second);
            eulerChart.push_back({node, it.second});
        }
    }
}

inline void rangeMaximumQuery(){
    length[0] = eulerChart.size();
    depth = log2(length[0]);

    for ( int index = 0; index < length[0]; index++ )
        rangeMaximum[0][index+1] = eulerChart[index].second;

    for ( int indexY = 1; indexY <= depth; indexY++ )
        length[indexY] = length[indexY-1] - ( 1<<(indexY-1) );

    for ( int indexY = 1; indexY <= depth; indexY++ )
        for ( int indexX = 1; indexX <= length[indexY]; indexX++ )
            rangeMaximum[indexY][indexX] = max( rangeMaximum[indexY-1][indexX], rangeMaximum[indexY-1][indexX+(1<<(indexY-1))] );
}

inline void answerQuery(){
    int first, second;
    for ( ; totalQuestions; totalQuestions-- ){
        fin >> first >> second;
        first = position[first];
        second = position[second];
        if ( first > second )
            swap(first, second);
        first++;
        int lengthPeriod = second - first + 1;
        int maxPeriod = 1 << ( (int)(log2(lengthPeriod)) );
        int indexY = log2(maxPeriod);
        fout << max ( rangeMaximum[indexY][first], rangeMaximum[indexY][second-(1<<indexY)+1]) << "\n";
    }
}

inline void debuggingPurposes(){
    for ( auto it : eulerChart )
        cout << it.first << " ";
    cout << "\n";
    for ( auto it : eulerChart )
        cout << it.second << " ";
    cout << "\n\n";
    for ( int index = 1; index <= totalNodes; index++ )
        cout << index << ": " << position[index] << "\n";

    for ( int indexY = 0; indexY <= depth; indexY++ ){
        for ( int indexX = 1; indexX <= length[indexY]; indexX++ )
            cout << rangeMaximum[indexY][indexX] << " ";
        cout << "\n";
    }
}

int main(){
    readVariables();
    partialArbore();
    deepFirstSearch();
    rangeMaximumQuery();
    answerQuery();
    return 0;
}