Cod sursa(job #1455538)

Utilizator theprdvtheprdv theprdv Data 28 iunie 2015 13:04:32
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <queue>
#define MAXN 15001
#define PII pair<int, int>
#define foreach(V) for(decltype((V).begin()) it = (V).begin(); it != (V).end(); ++it)

using namespace std;

struct node {
	int c, n;
} add; 

struct h_elem{
	int fath, n, c;
} h_add;

class cmp{
public:
	bool operator()(h_elem x, h_elem y) { return x.c > y.c; }
};

int N, M, K, no, max_h;
int Lev[MAXN], Log[2 * MAXN], R[15][2 * MAXN], Fs[MAXN];
node D[15][MAXN];
vector <node> G[MAXN];
vector <int> L[MAXN];
bool used[MAXN];

inline int max(const int x, const int y) { return (x > y) ? x : y; }
inline int min(const int x, const int y) { return (x < y) ? x : y; }
inline int min_lev(const int x, const int y) { return Lev[x] < Lev[y] ? x : y; }

void APM(){
	priority_queue <h_elem, vector <h_elem>, cmp> heap;

	for (int i = 1; i <= N; ++i)
		if (!used[i]){
			h_add.n = i, h_add.c = h_add.fath = 0;
			heap.push(h_add);

			while (!heap.empty()){
				int n = heap.top().n, c = heap.top().c, r = heap.top().fath;
				heap.pop();
				if (used[n]) continue;
				D[0][n].n = r, D[0][n].c = c;
				used[n] = 1;

				foreach(G[n])
					if (!used[it->n])
						h_add.n = it->n, h_add.c = it->c, h_add.fath = n,
						heap.push(h_add);
			}
		}

	for (int i = 1; i <= N; ++i)
		if (D[0][i].n)
			L[D[0][i].n].push_back(i);
}

void DFS(int n, int lv){
	used[n] = 0;
	Fs[n] = ++no, Lev[n] = lv, R[0][no] = n;
	max_h = max(max_h, lv);

	foreach(L[n])
		DFS(*it, lv + 1),
		R[0][++no] = n;
}

inline int LCA(int x, int y){
	x = Fs[x], y = Fs[y];
	if (x > y) x ^= y ^= x ^= y;
	int diff = y - x + 1, row = Log[diff];

	return min_lev(R[row][x], R[row][x + diff - (1 << row)]);
}

int find_dist(int x, int y){
	int q = Lev[x] - Lev[y], maxx = 0;

	while (q)
		maxx = max(maxx, D[Log[q]][x].c),
		x = D[Log[q]][x].n,
		q -= (1 << Log[q]);
	return maxx;
}

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

	scanf("%d %d %d", &N, &M, &K);
	for (int x, y, c; M; --M)
		scanf("%d %d %d", &x, &y, &c),
		add.n = x, add.c = c, G[y].push_back(add),
		add.n = y, G[x].push_back(add);
	APM();
	for (int i = 1; i <= N; ++i)
		if (used[i]) DFS(i, 1);

	/* Range Minimum Query precompute */
	for (int i = 1; (1 << i) <= no; ++i)
		for (int j = 1; j <= no - (1 << i) + 1; ++j)
			R[i][j] = min_lev(R[i - 1][j], R[i - 1][j + (1 << (i - 1))]);

	/* compute max distance between x and 2^i-th father of x */
	for (int i = 1; (1 << i) <= max_h; ++i)
		for (int j = 1; j <= N; ++j)
			if (Lev[j] > (1 << i))
				D[i][j].n = D[i - 1][D[i - 1][j].n].n,
				D[i][j].c = max(D[i - 1][j].c, D[i- 1][D[i - 1][j].n].c);

	for (int i = 2; i <= no; ++i) Log[i] = Log[i >> 1] + 1;

	for (int node, x, y; K; --K){
		scanf("%d %d", &x, &y);
		node = LCA(x, y);
		if (x == y) 
			printf("-1\n");
		else printf("%d\n", max(find_dist(x, node), find_dist(y, node)));
	}

	return 0;
}