Cod sursa(job #20792)

Utilizator webspiderDumitru Bogdan webspider Data 22 februarie 2007 12:03:29
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.51 kb
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

vector<int> fii[16001];
vector<int> cost[16001];
vector<int> muchii[3];

int stram[16001][20];
int muchi[16001][20];

int heap[30001];
int repr[16001];

int n,m,k,lh;

void pop ( int x );
void push ( int x );
void DFS ( int nodc, int app );
void make_mat();
int findrep( int x );
int find_cost( int nod1, int nod2 );

int main()
{
	int i,j;
	int a,b,c;

	freopen("radiatie.in","r",stdin);
	freopen("radiatie.out","w",stdout);
	
	muchii[0].push_back(0);
	muchii[1].push_back(0);
	muchii[2].push_back(0);

	scanf("%d %d %d\n", &n, &m, &k);
	for ( i = 1; i <= m; i++ )
	{
		scanf("%d %d %d\n", &a, &b, &c );
		muchii[0].push_back( a );
		muchii[1].push_back( b );
		muchii[2].push_back( c );
		lh++;
		heap[ lh ] = i;
		pop( lh );
	}

	while ( lh )
	{
		a = findrep( muchii[0][heap[1]] );
		b = findrep( muchii[1][heap[1]] );
		if ( a != b ) 
		{
			fii[ muchii[0][heap[1]] ].push_back( muchii[1][ heap[1] ] );
			fii[ muchii[1][heap[1]] ].push_back( muchii[0][ heap[1] ] );

			cost[ muchii[0][heap[1]] ].push_back( muchii[2][ heap[1] ] );
			cost[ muchii[1][heap[1]] ].push_back( muchii[2][ heap[1] ] );

			repr[ max(a,b) ] = min( a,b );
			
		}
		heap[1] = heap[lh];
		lh--;
		push( 1 );
	}

	bzero( repr, sizeof ( repr ) );
	
	muchii[0].clear();
	muchii[1].clear();
	muchii[2].clear();


	DFS( 1, 1);

	make_mat();

	for ( i = 1; i <= k; i++ )
	{
		scanf("%d %d\n", &a, &b );
		printf("%d\n", find_cost( a, b ) );
	}

	fclose(stdin);
	fclose(stdout);

	return 0;
}

int find_cost( int nod1, int nod2 )
{
	int l,t,u;
	int i,j;
	int dif_niv;
	int aux1, aux;
	int ur1=0, ur2=0;

	if ( repr[ nod1 ] > repr[ nod2 ] ) {
		aux = nod1; nod1 = nod2; nod2 = aux;
	}

	dif_niv = repr[ nod2 ] - repr[ nod1 ];
	for ( t=1, u = 0 ; t <= dif_niv; t <<= 1, u++ );

	for ( i = u; i >= 0; i-- )
	{
		if ( dif_niv & ( 1 << i ) )
		{
			ur2 = max( ur2, muchi[ nod2 ][ i ] );
			nod2 = stram[ nod2 ][ i ];
		}
	}
	aux = nod1; aux1 = nod2;

	dif_niv = repr[ nod1 ];

	for ( t=1, u=0; t <= dif_niv; t <<= 1, u++ );

	for ( i=u; i >= 0; i--  )
	{
		if ( stram[ aux ][ i ] != stram[ aux1 ][i] )
		{
			ur1 = max( ur1, muchi[aux][i] );
			aux = stram[ aux ][ i ];
			ur2 = max( ur2, muchi[aux1][i] );
			aux1 = stram[ aux1 ][ i ];
		}
	}
	if ( aux != aux1 )
	{
		ur1 = max ( ur1, muchi[ aux ][ 0 ] );
		ur2 = max ( ur2, muchi[ aux1 ][ 0 ] );
	}

	return max( ur1, ur2 );
}




void make_mat()
{
	int u,t;
	int i,j;

	for ( u = 1, t=0; u < n; u<<=1, t++ );

	for ( i = 1 ; i <= t; i++ )
		for ( j = 1; j <= n; j++ )
	{
		stram[ j ][ i ] = stram[ stram[ j ][ i - 1 ] ][ i - 1 ];
		if ( stram[j][i] )
		muchi[ j ][ i ] = max ( muchi[ j ][ i - 1 ], muchi[ stram[ j ][ i - 1 ] ][ i - 1 ] );
	}
}

void DFS ( int nodc, int add )
{
	int i;
	repr[ nodc ] = add;


	for ( i = 0; i < fii[ nodc ].size(); i++ )
		if ( !repr[ fii[nodc][i] ] )
		{
			stram[ fii[nodc][ i ] ][0] = nodc;
			muchi[ fii[nodc][ i ] ][0] = cost[nodc][i];
			DFS( fii[nodc][i] , add+1);
		}

}

int findrep( int x )
{
	int a = x;
	while ( repr[a] != 0 )
		a = repr[a];
	return a;
}

void pop( int x )
{
	int aux;
	while ( x > 1 && muchii[2][ heap[x] ] < muchii[2][ heap[x/2] ] )
	{
		aux = heap[x];
		heap[x] = heap[x/2];
		heap[x/2] = aux;

		x = x/2;
	}	
}

void push( int x )
{
	int q = 0, aux;

	while ( x != q )
	{
		q = x;
		if ( 2*q <= lh && muchii[2][ heap[x] ] > muchii[2][ heap[2*q] ] )
			x = 2*q;
		if ( 2*q+1 <= lh && muchii[2][ heap[x] ] > muchii[2][ heap[2*q+1] ] )
			x = 2*q+1;

		aux = heap[x];
		heap[x] = heap[q];
		heap[q] = aux;
	}
}