Cod sursa(job #568541)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 31 martie 2011 13:19:11
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
#include<stdio.h>
#include<algorithm>
#include<vector>

#define maxN 15005
#define maxM 30005

using namespace std;

FILE*f=fopen("radiatie.in","r");
FILE*g=fopen("radiatie.out","w");

int n,m,q,i,k,T[maxN],Eul[maxN<<1],Niv[maxN<<1],Fap[maxN],Viz[maxN],E[maxN<<1];
int k2,M[17][maxN<<1],D[17][maxN],Nivmax,Dist[maxN],Str[17][maxN],j;
int ii,x,y,e,R,Lca,D1,D2,Sol;

vector<int>W[maxN],C[maxN];

struct mch{
	int x;
	int y;
	int cst;
}A[maxM];

int cmp ( mch a, mch b ){
	return a.cst < b.cst;
}

int root ( int nod ){
	int nod2 = nod;
	
	for( ; T[nod2] > 0 ; nod2 = T[nod2] );
	
	for ( ; T[nod] > 0 ; nod = T[nod] ){
		T[nod] = nod2;
	}
	
	return nod2;
}

void unify ( int nod1 , int nod2 ){
	int ra = root(nod1);
	int rb = root(nod2);
	
	if ( T[ra] < T[rb] ){
		T[ra] += T[rb];
		T[rb] = ra;
	}
	else{
		T[rb] += T[ra];
		T[ra] = rb;
	}
	
}

void dfs( int nod , int nivel ){
	
	Eul[++k] = nod;
	Niv[k] = nivel;
	Fap[nod] = k;
	Viz[nod] = 1;
	Dist[nod] = nivel;
	if ( Dist[nod] > Nivmax )	Nivmax = Dist[nod];
	
	for ( int i = 0 ; i < W[nod].size() ; ++i ){
		int vcn = W[nod][i];
		if ( !Viz[vcn] ){
			Str[0][vcn] = nod;
			D[0][vcn] = C[nod][i];
			dfs(vcn,nivel+1);
			Eul[++k] = nod;
			Niv[k] = nivel;
		}
	}
	
}

void Rmq () {
	
	for ( i = 2 ; i <= k ; ++i ){
		E[i] = E[i>>1] + 1;
	}
	for ( i = 1 ; i <= k ; ++i ){
		M[0][i] = i;
	}
	
	for ( k2 = 1 ; k2 <= E[k] ; ++k2 ){
		
		for ( i = 1 ; i + ( 1 << k2 ) <= k ; ++i ){
			
			M[k2][i] = M[k2-1][i];
			
			if ( Niv[M[k2][i]] > Niv[M[k2-1][i+(1 << (k2 - 1))]] )
				M[k2][i] = M[k2-1][i+(1<<(k2-1))];
			
		}
		
	}
	
}

void fct ( int d , int x ){
	
	int p = 0;
	
	while ( d ){
		if ( d & 1 ){
			Sol = max( Sol, D[p][x] );
			x = Str[p][x];
		}
		++p;
		d = d >> 1;
	}
	
}

int main () {
	
	fscanf(f,"%d %d %d",&n,&m,&q);
	
	for ( i = 1 ; i <= m ; ++i ){
		fscanf(f,"%d %d %d",&A[i].x,&A[i].y,&A[i].cst);
	}
	
	sort(A+1,A+m+1,cmp);
	
	for ( i = 1 ; i <= n ; ++i ){
		T[i] = -1;
	}
	
	for ( i = 1 ; i <= m && k < n - 1 ; ++i ){
		
		if ( root( A[i].x ) != root( A[i].y ) ){
			
			unify(A[i].x,A[i].y); ++k;
			
			W[A[i].x].push_back(A[i].y);
			W[A[i].y].push_back(A[i].x);
			C[A[i].x].push_back(A[i].cst);
			C[A[i].y].push_back(A[i].cst);
			
		}
		
	}
	
	k = 0;
	
	dfs(1,0);
	
	Rmq();
	
	//D[j][i] = maximul de pe drumul de lungime 2^j din nodul i
	
	
	
	for ( j = 1 ; j <= E[Nivmax] ; ++j ){
		for ( i = 1 ; i <= n ; ++i ){
			
			Str[j][i] = Str[j-1][Str[j-1][i]];
			D[j][i] = max(D[j-1][i],D[j-1][Str[j-1][i]]);
			
		}
	}
	
	for ( ii = 1 ; ii <= q ; ++ii ){
		fscanf(f,"%d %d",&x,&y);
		
		if ( Fap[x] > Fap[y] )	swap(x,y);
		
		e = E[ Fap[y] - Fap[x] + 1];
		
		R = M[e][Fap[x]];
		
		if ( Niv[R] > Niv[M[e][Fap[y] - ( 1 << e ) + 1]] )
			R = M[e][Fap[y] - ( 1 << e ) + 1];
		
		Lca = Eul[ R ];
		
		D1 = Dist[x] - Dist[Lca];
		D2 = Dist[y] - Dist[Lca];
		
		Sol = 0;
		
		fct(D1,x);
		fct(D2,y);
		
		fprintf(g,"%d\n",Sol);
		
	}
	
	fclose(f);
	fclose(g);
	
	return 0;
}