Cod sursa(job #393547)

Utilizator vladiiIonescu Vlad vladii Data 9 februarie 2010 17:27:54
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
#define INF 100000000
#define nst (nod << 1)
#define ndr (nst + 1)
#define mij ((li + lf) >> 1)
int N, M, K, st, dr, sol, hsol;
int A[4*15002+66];
int Arb[15002], H[45003], L[45003], poz[15002], dist[15002], k;
struct Tati {
    int t;
    int c;
} tata[15002], stra[16][15002];
bool viz[15002];
vector<pair<int, int> > G[15002];
struct Muchii {
    int x;
    int y;
    int c;
} Mc[30002];

int cmp(Muchii a, Muchii b) {
    return a.c<b.c;
}

int CC(int nod) {
    while(Arb[nod]!=nod) {
         nod=Arb[nod];
    }
    return nod;
}

void Un(int nod1, int nod2) {
    Arb[nod2]=nod1;
}

void DetArbore(int nod) {
     int p, q;
     queue<int> Q;
     vector<pair<int, int> > X;
     viz[nod]=1;
     Q.push(nod);
     while(!Q.empty()) {
          p=Q.front(); Q.pop();
          for(vector<pair<int, int> >::iterator it=G[p].begin(); it!=G[p].end(); it++) {
              if(!viz[(*it).first]) {
                   viz[(*it).first]=1;
                   X.push_back(make_pair((*it).first, (*it).second));
                   Q.push((*it).first);
              }
          }
          G[p].clear();
          for(vector<pair<int, int> >::iterator it=X.begin(); it!=X.end(); it++) {
               tata[(*it).first].t=p;
               tata[(*it).first].c=(*it).second;
               G[p].push_back(make_pair((*it).first, (*it).second));
          }
          X.clear();
     }
}

void Euler(int nod, int lev) {
     H[++k]=nod;
     L[k]=lev;
     poz[nod]=k;
     for(vector<pair<int, int> >::iterator it=G[nod].begin(); it!=G[nod].end(); it++) {
          Euler((*it).first, lev+1);
          H[++k]=nod;
          L[k]=lev;
     }
}

void builda(int nod, int li, int lf) {
	if(li == lf)
	{
		A[nod] = li;
		return;
	}

	builda(nst, li, mij);
	builda(ndr, mij+1, lf);

	if(L[A[nst]] <= L[A[ndr]])
		A[nod] = A[nst];
	else
		A[nod] = A[ndr];
}

void query(int nod, int li, int lf) {
	if(st <= li && lf <= dr)
	{
		if(L[A[nod]] < hsol)
			sol = H[A[nod]],
			hsol = L[A[nod]];
		return;
	}

	if(st <= mij) query(nst, li, mij);
	if(mij < dr)  query(ndr, mij+1, lf);
}

int lca(int x, int y) {
	st = poz[x], dr = poz[y];
	if(st > dr) swap(st, dr);
	sol = hsol = INF;
	query(1, 1, k);

	return sol;
}

int main() {
    fstream f1, f2;
    int i, j, p, q, x, y, d, n, maxim;
    f1.open("radiatie.in", ios::in);
    f1>>N>>M>>K;
    for(i=1; i<=M; i++) {
         f1>>Mc[i].x>>Mc[i].y>>Mc[i].c;
    }
    sort(Mc+1, Mc+M+1, cmp);
    for(i=1; i<=N; i++) {
         Arb[i]=i;
    }
    for(i=1; i<=M; i++) {
         //aleg muchia i doar daca Mc[i].x si Mc[i].y se afla in comp conexe diferite
         if(CC(Mc[i].x)!=CC(Mc[i].y)) {
              //folosesc muchia Mc[i].x -> Mc[i].y;
              G[Mc[i].x].push_back(make_pair(Mc[i].y, Mc[i].c));
              G[Mc[i].y].push_back(make_pair(Mc[i].x, Mc[i].c));
              //unesc pe Mc[i].x cu Mc[i].y;
              Un(Mc[i].x, Mc[i].y);
         }
    }
    DetArbore(1);
    tata[1].t=1; tata[1].c=0;
    for(i=1; i<=N; i++) {
         dist[i]=dist[tata[i].t]+1;
         stra[0][i].t=tata[i].t;
         stra[0][i].c=tata[i].c;
    }
    for(i=1; i<=15; i++) {
         for(j=1; j<=N; j++) {
              stra[i][j].t=stra[i-1][stra[i-1][j].t].t;
              stra[i][j].c=max(stra[i-1][j].c, stra[i-1][stra[i-1][j].t].c);
         }
    }
    Euler(1, 0);
    builda(1, 1, k);
    f2.open("radiatie.out", ios::out);
    for(i=1; i<=K; i++) {
         f1>>p>>q;
         if(p==q) {
              f2<<0<<endl;
         }
         else {
              x=lca(p, q);
              //aflu maximul pe intervalele (p, x) si (q, x);
              d=dist[p]-dist[x];
              j=0; n=p; maxim=0;
              while(d) {
                   if(d%2) {
                        maxim=max(maxim, stra[j][n].c);
                        n=stra[j][n].t;
                   }
                   j++; d=d>>1;
              }
              d=dist[q]-dist[x];
              j=0; n=q;
              while(d) {
                   if(d%2) {
                        maxim=max(maxim, stra[j][n].c);
                        n=stra[j][n].t;
                   }
                   j++; d=d>>1;
              }
              f2<<maxim<<endl;
         }
    }
    f1.close(); f2.close();
    return 0;
}