Cod sursa(job #229381)

Utilizator Adriana_SAdriana Sperlea Adriana_S Data 9 decembrie 2008 23:33:41
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.57 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

const int M_MAX = 30010;
const int N_MAX = 15010;
const int INF = 2000000000;

int N;
pair <int, pair <int, int>  > mch[M_MAX];
vector <pair <int, int> > G[N_MAX];
int rep[N_MAX], nr[N_MAX];
int lg[2 * N_MAX], level[N_MAX], parc[2 * N_MAX], vec, rmq[25][2 * N_MAX], tata[N_MAX];
int fap[N_MAX], din[20][N_MAX], stram[25][N_MAX];

void euler(int nod)
{
	parc[++ parc[0]] = nod;
	fap[nod] = parc[0];
	for (vector <pair <int, int> >::iterator it = G[nod].begin(); it != G[nod].end(); ++ it) {
		vec = it -> second;
		if (!level[vec]) {
			tata[vec] = it -> first;
			stram[0][vec] = nod;
			level[vec] = level[nod] + 1;
			euler(vec);
			parc[++ parc[0]] = nod;
		}
	}
}

inline int MIN(int a, int b)
{
	return (a < b ? a : b);
}

inline int MAX(int a, int b)
{
	return (a > b ? a : b);
}

int find_stramos(int nod, int ram)
{
	int step, str = nod, i;
	for (step = 1, i = 0; step < ram; step <<= 1, i ++);
	for (; step; step >>= 1, i --) {
		if (ram & step) {
			str = stram[i][str];
		}
	}
	return str;
}

int dist(int nod, int care)
{
	int l = lg[care];
	int mn = din[l][nod], ram = care - (1 << l);
	if (ram) {
		int str = find_stramos(nod, ram);
		mn = MAX(mn, din[l][str]);
	}

	return mn;
}

int find_rep(int nod)
{
	while (rep[nod] != nod) {
		nod = rep[nod];
	}
	return nod;
}

void join(int r1, int r2)
{
	if (nr[r1] < nr[r2]) {
		rep[r1] = r2;
		nr[r2] += nr[r1];
		nr[r1] = 0;
	} else {
		rep[r2] = r1;
		nr[r1] += nr[r2];
		nr[r2] = 0;
	}
}

int main()
{
	freopen("radiatie.in", "r", stdin);
#ifndef _SCREEN_
	freopen("radiatie.out", "w", stdout);
#endif

	int M, K, a, b, c;
	scanf("%d %d %d\n", &N, &M, &K);
	for (int i = 1; i <= M; i ++) {
		scanf("%d %d %d\n", &a, &b, &c);
		mch[i] = make_pair(c, make_pair(a, b));
	}
	sort(mch + 1, mch + M + 1);
	for (int i = 1; i <= N; i ++) {
		rep[i] = i;
		nr[i] = 1;
	}

	for (int i = 1; i <= M; i ++) {
		int x = mch[i].second.first, y = mch[i].second.second;
		int r1 = find_rep(x), r2 = find_rep(y);
//		printf("x = %d y = %d r1 = %d r2 = %d\n", x, y, r1, r2);
		if (r1 != r2) {
			join(r1, r2);
			G[x].push_back(make_pair(mch[i].first, y));
			G[y].push_back(make_pair(mch[i].first, x));
		}
	}

	level[1] = 1;
	euler(1);
	lg[1] = 0;
	for (int i = 2; i <= parc[0]; i ++) {
		lg[i] = lg[i >> 1] + 1;
	}

	for (int j = 1; j <= parc[0]; j ++) rmq[0][j] = j;
	for (int i = 1; i <= lg[parc[0]]; i ++) {
		for (int j = 1; j + (1 << i) - 1 <= parc[0]; j ++) {
			int st = rmq[i - 1][j], dr = rmq[i - 1][j + (1 << (i - 1))];
			if (level[parc[st]] < level[parc[dr]]) rmq[i][j] = st;
			else rmq[i][j] = dr;
		}
	}

	for (int i = 1; i <= lg[N]; i ++) {
		for (int j = 1; j <= N; j ++) {
			stram[i][j] = stram[i - 1][stram[i - 1][j]];
		}
	}

	for (int i = 1; i <= N; i ++) {
		din[0][i] = tata[i];
	}
	for (int j = 1; j <= N; j ++) {
		for (int i = 1; i <= lg[level[j] - 1]; i ++) {
			din[i][j] = MAX(din[i - 1][stram[i - 1][j]], din[i - 1][j]);
		}
	}

	int X, Y;
	for (int i = 1; i <= K; i ++) {
		scanf("%d %d\n", &X, &Y);
		int st = MIN(fap[X], fap[Y]), dr = MAX(fap[X], fap[Y]);
		int L = dr - st + 1;
 
		int lca;
		if (level[parc[rmq[lg[L]][st]]] < level[parc[rmq[lg[L]][st + L - (1 << lg[L])]]]) {
			lca = parc[rmq[lg[L]][st]];
		} else {
			lca = parc[rmq[lg[L]][st + L - (1 << lg[L])]];
		}
		int unde = level[lca];

		int rez = 0;
		if (lca != X && lca != Y) {
			rez = MAX(dist(X, level[X] - unde), dist(Y, level[Y] - unde));
		}
		if (lca == X) {
			rez = dist(Y, level[Y] - unde);
		}
		if (lca == Y) {
			rez = dist(X, level[X] - unde);
		}
		if (X == Y) rez = 0;
		printf("%d\n", rez);
	}

	return 0;
}