Cod sursa(job #1489686)

Utilizator horiainfoTurcuman Horia horiainfo Data 21 septembrie 2015 20:53:38
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>

#define INF 1000000000
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

short int mat[15][15003], poz[15003], deep[30003], v[30003], ant[15003];
int lg_ant[15003],n,m,k,lgV;
vector<int> nod_edge[15003];
struct EDGE{int x,y,lg; bool viz;} edge[30003];

bool test(EDGE x,EDGE y)
{
    return x.lg<y.lg;
}

void compression(int x,int root)
{
    int aux;
    while(ant[x]!=root)
    {
        aux = ant[x];
        ant[x] = root;
        x = aux;
    }
}

int root(int nod)
{
    while(ant[nod]!=nod)
        nod=ant[nod];
    return nod;
}

void APM()
{
    int nrEdges=0;
    int r1,r2;
    for(int i=1;i<=n;i++)
        ant[i]=i;
    for(int i=1;nrEdges<n-1;i++)
    {
        r1 = root(edge[i].x);
        r2 = root(edge[i].y);
        if(r1!=r2)
        {
            nrEdges++;
            nod_edge[edge[i].x].push_back(i);
            nod_edge[edge[i].y].push_back(i);
            ant[r2]=r1;

            compression(edge[i].x,r1);
            compression(edge[i].y,r1);
        }
    }
}

int new_nod;
void euler(int nod,int actual_deep)
{
    v[++lgV] = nod; deep[lgV] = actual_deep;
    poz[nod] = lgV;

    for(int i=nod_edge[nod].size()-1;i>=0;i--)
        if(edge[nod_edge[nod][i]].viz==false)
        {
            edge[nod_edge[nod][i]].viz = true;
            new_nod = edge[nod_edge[nod][i]].x == nod ? edge[nod_edge[nod][i]].y : edge[nod_edge[nod][i]].x;

            ant[new_nod] = nod; lg_ant[new_nod] = edge[nod_edge[nod][i]].lg;
            euler(new_nod,actual_deep+1);
            v[++lgV] = nod; deep[lgV] = actual_deep;
        }
}

void RMQ()
{
    long long pow2,i,j;
    for(i=1;i<=lgV;i++)
        mat[i][0]=i;

    for(j=1;(pow2 = (1<<j))<lgV;j++)
        for(i=1; i+pow2-1 <= lgV; i++)
            mat[i][j] = deep[mat[i][j-1]] < deep[mat[i+pow2/2][j-1]] ?  mat[i][j-1] : mat[i+pow2/2][j-1];
}

void LCA()
{
    euler(1,0);
    RMQ();
}

int RMQuery(int inc,int sf)
{
    int col = log2 (sf-inc+1);
    if(deep[mat[inc][col]] < deep[mat[(inc+sf+1)/2][col]])
        return mat[inc][col];
    else
        return mat[(inc+sf+1)/2][col];
}

int max_edge(int x,int ancestor)
{
    int edge_max = 0;
    while(x!=ancestor)
    {
        if(lg_ant[x] > edge_max)
            edge_max = lg_ant[x];
        x = ant[x];
    }
    return edge_max;
}

int main()
{
    fin>>n>>m>>k;
    for(int i=1;i<=m;i++)
        fin>>edge[i].x>>edge[i].y>>edge[i].lg;
    sort(edge+1,edge+m+1,test);

    APM();
    LCA(); // lowest common ancestor

    int ancestor_poz,x,y;
    for(int i=1;i<=k;i++)
    {
        fin>>x>>y;
        ancestor_poz = RMQuery(min(poz[x],poz[y]),max(poz[x],poz[y]));
        fout<<max(max_edge(x,v[ancestor_poz]),max_edge(y,v[ancestor_poz]))<<'\n';
    }
    return 0;
}