Cod sursa(job #305685)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 18 aprilie 2009 12:00:17
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
#define mp make_pair
#define pb push_back
#define MAX 30010
#define LOG 20
#define FOR(A,B) for (A=0; A<B; ++A)
#define size(X) (int)X.size()
#define f first
#define s second
#define trace(x) cerr<<#x<<" = "<<x<<"\n";
ifstream in("radiatie.in");
ofstream out("radiatie.out");

struct muchie { 
	int x, y, c;
	muchie(int _x, int _y, int _c) { x=_x, y=_y, c=_c; }
};
typedef pair<int,int> pii;

vector<pii> G[MAX];
vector<muchie> muchii;
int N, M, Q, i;
bool U[MAX];
int T[MAX][LOG], D[MAX][LOG];
int H[MAX], Log[MAX];
int pT[MAX], pLg[MAX];

int comp_muchii(muchie A, muchie B) { return A.c < B.c; }

void DF(int n, int t, int d) {
	if ( U[n] ) return;
	U[n] = true;
	H[n] = H[t]+1;
	D[n][0] = d;

	int r, i;
	for (r=0, i=t; i; i=T[i][r++]) {
		D[n][r+1] = max(D[n][r], D[i][r]);
		T[n][r] = i;
	}

	FOR(i, size(G[n])) 
		DF(G[n][i].f, n, G[n][i].s);
}

int tata(int x) { return pT[x] == x ? x : pT[x] = tata(pT[x]); }
void reuneste(int a, int b) {
	if ( pLg[a] == pLg[b] ) 
		pLg[ pT[b] = a ]++;
	else {
		if ( pLg[a] < pLg[b] ) 
			pT[a] = b;
		else
			pT[b] = a;
	}
}

int lca_dubios(int a, int b) {
	int dd = 0;
//	cerr << "**\n";
//	trace(a); trace(b);
	while ( H[a]>H[b] ) {
		dd = max(dd, D[a][Log[H[a]-H[b]]]);
		a = T[a][Log[H[a]-H[b]]];
//		trace(a);
	}
	while ( H[b]>H[a] ) {
		dd = max(D[b][Log[H[b]-H[a]]], dd);
		b = T[b][Log[H[b]-H[a]]];
//		trace(b);
	}
	while ( H[a]==H[b] && a!=b ) {
		int p;
		for (p=Log[H[a]]; p; p--)
			if ( T[a][p]!=T[b][p] ) 
				break;
		dd = max(max(dd, D[a][p]), D[b][p]);
		a = T[a][p]; b = T[b][p];
//		trace(a); trace(b);
	}
	return dd;
}

void precalc() {
	for (int i=2; i<=N; ++i) Log[i] = Log[i>>1] + 1;
}

int main() {
	in >> N >> M >> Q;
	while ( M-- ) {
		int x, y, c;
		in >> x >> y >> c;
		muchii.pb( muchie(x, y, c) );
	}

	precalc();
	// scoatem APM
	sort(muchii.begin(), muchii.end(), comp_muchii);
	FOR (i,N) pT[i+1] = i+1;
	FOR (i, size(muchii)) {
		int x = muchii[i].x, y = muchii[i].y, c = muchii[i].c;
		int ta = tata(x), tb = tata(y);
		if ( ta==tb ) continue;
		reuneste(ta, tb);
		G[x].pb(mp(y, c));
		G[y].pb(mp(x, c));
//		trace(x); trace(y);
	}

	// scoatem arborescente
	// si facem LCA dubios
	// de fapt facem tabela de stramosi in DF
	FOR (i, N) 
		DF(i+1, 0, 0);

	// raspundem la queryuri
	while ( Q-- ) {
		int x, y;
		in >> x >> y;
		out << lca_dubios(x, y) << "\n";
	}

	return 0;
}