Cod sursa(job #1156016)

Utilizator omerOmer Cerrahoglu omer Data 27 martie 2014 12:48:43
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.04 kb
#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
const int N=15001, LOG=16;
using namespace std;
FILE *f,*g;

int parent[N], depth[N]; int n,m,k;                          //pentru multimi disjuncte

struct nod{

    int x,y,val;
    bool operator< (nod const &b) const{

        return val>b.val;
    }
};

priority_queue<nod> edges; vector<pair<int, int> > graph[N];     //in edges tinem valorile muchiilor in heap, pt kruskal; graph va avea padurea de cost minim

int stramos[N][LOG+1], maxval[N][LOG+1];  bool seen[N];  int adanc[N];            //stramos[v][i] are stramosul 2^i al lui v; maxval[v][i] are valoarea maxima a unei muchii de la v la stramosul 2^i

void read(void){

    f=fopen("radiatie.in","r");
    g=fopen("radiatie.out","w");
    
    fscanf(f,"%d%d%d",&n,&m,&k);

    int i; nod dumm;
    for(i=1; i<=m; i++){
        
        fscanf(f,"%d%d%d",&dumm.x,&dumm.y,&dumm.val);
        edges.push(dumm);
    }
}

void initparents(void){

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

int findparent(int v){

    if (v == parent[v]) return v;
    else{
    parent[v] = findparent(parent[v]);
    return parent[v];
    }
}

void unite(int x,int y,int val){

if (findparent(x) != findparent(y)){

    graph[x].push_back (make_pair (y,val) );
    graph[y].push_back (make_pair (x,val) );

    x=findparent(x);
    y=findparent(y);
    
    if (x != y){
    if (depth[x] < depth[y]) parent[x]=y;
    else if (depth[x] == depth[y]) {parent[x] = y; depth[y]++; }
         else parent[y] = x;

    }
}
}

void kruskal(void){

    nod dumm;
    while (! edges.empty()){

        dumm = edges.top();
        edges.pop();

        unite(dumm.x,dumm.y,dumm.val);
    }
}

void resolvevertex(int v){

    vector<pair<int, int> >::iterator it=graph[v].begin();  int i;
    seen[v]=1;

    while(it != graph[v].end() ){

          if ( ! seen[it->first] ){
                
                stramos[it->first][0]=v;
                for(i=1; i<=LOG; i++) stramos[it->first][i]=stramos[stramos[it->first][i-1]][i-1];
                maxval[it->first][0]=it->second;
                for(i=1;i<=LOG; i++) maxval[it->first][i] = max( maxval[it->first][i-1], maxval[stramos[it->first][i-1]][i-1]);
                

                adanc[it->first]=adanc[v]+1;

                resolvevertex(it->first);

                
          }

          it++;
    }
}

void findstramosi(void){

    int i,j;
    for(i=1;i<=n;i++){

        if (! seen[i]){

            for(j=0; j<=LOG; j++) {stramos[i][j]=i; maxval[i][j]=0;}
            resolvevertex(i);
        }
    }
}

pair<int,int> damistramos(int v, int k){

    int i=1,t=0, maxim=-1;
    while (i<k) {i*=2;  t++;}

    while (k){

        if (k>=i) {
            if (maxval[v][t]>maxim) maxim=maxval[v][t];
            v=stramos[v][t];
            k-=i;
        }
        i/=2;
        t--;
    }

    return make_pair(v,maxim);
}

int findlca(int a, int b){

    if (a == b ) return 0;
    else{

        int i=LOG;
        while (stramos[a][i] == stramos[b][i]) i--;

        int maxim=-1;
        if (maxval[a][i]>maxim) maxim=maxval[a][i];
        if (maxval[b][i]>maxim) maxim=maxval[b][i];

        a=stramos[a][i]; b=stramos[b][i];
        i--;

        while(i>=0){

            if (stramos[a][i] != stramos[b][i]){

                if (maxim<maxval[a][i]) maxim=maxval[a][i];
                if (maxim<maxval[b][i]) maxim=maxval[b][i];

                a=stramos[a][i]; b=stramos[b][i];
            }

            i--;
        }

        if (maxim<maxval[a][0]) maxim=maxval[a][0];
        
        return maxim;
    }

}

int findmax(int a,int b){

    pair<int,int> aux;

    int maxim;

    if (adanc[a]<adanc[b]) swap(a,b);

    aux=damistramos(a,adanc[a]-adanc[b]);

    maxim=findlca(aux.first,b);

    if (aux.second>maxim) maxim=aux.second;

    return maxim;
}

void solve(void){

    int i; int a,b;
    for(i=1; i<=k; i++){
        
        fscanf(f,"%d%d",&a,&b);
        
        fprintf(g,"%d\n",findmax(a,b));
    }
}


int main(void){
    read();

    initparents();
    kruskal();

    findstramosi();

    solve();

    return 0;
}