Cod sursa(job #178295)

Utilizator Binary_FireFlorin Pogocsan Binary_Fire Data 14 aprilie 2008 13:01:32
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using namespace std;

#define DBxG
#define FL

#define fin  "radiatie.in"
#define fout "radiatie.out"

#define mp make_pair
#define pb push_back
#define sz(c) (int)((c).size())
#define f first
#define s second

const int Nmax = 15010;
const int LgMax = 19;

int N,M,K;
int dp[LgMax][Nmax],str[LgMax][Nmax];

int comp[Nmax],nivel[Nmax];
vector < pair<int,pair<int,int> > > v;

vector <int> g[Nmax],cost[Nmax];

char viz[Nmax];

void readdata()
{
	int i,x,y,c;

	freopen(fin,"r",stdin);
#ifdef FL
	freopen(fout,"w",stdout);
#endif
	scanf("%d%d%d",&N,&M,&K);

	for ( i = 1; i <= M; ++i )
	{
		scanf("%d%d%d",&x,&y,&c);
		v.pb(mp(c,mp(x,y)));
	}
}

int componenta(int x)
{
	if ( comp[x] != x )
		comp[x] = componenta(comp[x]);
	return comp[x];
}

void uneste(int x,int y)
{
	if ( rand() & 1 )
		comp[x] = y;
	else
		comp[y] = x;
}

void apm()
{
	int i,x,y;

	sort(v.begin(),v.end());

	for ( i = 1; i <= N; ++i )
		comp[i] = i;
	
	srand(time(0));

	for ( i = 0; i < sz(v); ++i )
	{
		x = v[i].s.f; y = v[i].s.s;
		if ( componenta(x) != componenta(y) )
		{
			uneste(componenta(x),componenta(y));
			g[x].pb(y);
			g[y].pb(x);
			cost[x].pb(v[i].f);
			cost[y].pb(v[i].f);
#ifdef DBG
			printf("%d %d %d\n",v[i].s.f,v[i].s.s,v[i].f);
#endif
		}
	}
}

void dfinit(int x)
{
	int i;

	viz[x] = 1;

	for ( i = 0; i < sz(g[x]); ++i )
		if ( !viz[g[x][i]] )
		{
			str[0][g[x][i]] = x;
			dp[0][g[x][i]]  = cost[x][i];
			nivel[g[x][i]] = nivel[x] + 1;
			dfinit(g[x][i]);
		}
}

void prep()
{
	int i,j;

	for ( i = 1; i <= N; ++i )
		dfinit(i);

	for ( j = 1; j < LgMax; ++j )
	for ( i = 1; i <= N; ++i )
	{
		str[j][i] = str[j-1][str[j-1][i]];
		dp[j][i] = max(dp[j-1][i],dp[j-1][str[j-1][i]]);
	}

#ifdef DBG
	for ( j = 0; (1<<j) <= N; ++j, printf("\n") )
	for ( i = 1; i <= N; ++i )
		printf("%d ",str[j][i]);
	printf("\n");
	for ( j = 0; (1<<j) <= N; ++j, printf("\n") )
	for ( i = 1; i <= N; ++i )
		printf("%d ",dp[j][i]);
#endif
}

int query(int x,int y)
{
	int ret=0,i;

	if ( nivel[x] < nivel[y] )
		swap(x,y);

	while ( nivel[x] != nivel[y] )
	{
		for ( i = 0; nivel[x] - ( 1 << i ) >= nivel[y]; ++i );
		--i;
		ret = max(ret,dp[i][x]);
		x = str[i][x];
	}
	
	while ( x != y )
	{
		for ( i = 0; str[i][x] != str[i][y]; ++i );
		if ( i > 0 ) --i;
		ret = max(ret,dp[i][x]); ret = max(ret,dp[i][y]);
		x = str[i][x]; y = str[i][y];
	}

	return ret;
}

void answer()
{
	int x,y;

	while ( K-- )
	{
		scanf("%d %d\n",&x,&y);
		printf("%d\n",query(x,y));
	}
}

int main()
{
	readdata();
	apm();
	prep();
	answer();
	return 0;
}