Cod sursa(job #1455506)

Utilizator theprdvtheprdv theprdv Data 28 iunie 2015 08:01:07
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 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;

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

int N, M, K, no, max_h;
int Lev[MAXN], Log[MAXN], R[15][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 <PII, vector <PII>, cmp> heap;
	heap.push(make_pair(1, 0));
	used[1] = 1;

	while (!heap.empty()){
		int n = heap.top().first, c = heap.top().second;
		heap.pop();
		used[n] = 1;

		foreach(G[n])
			if (!used[it->n])
				heap.push(make_pair(it->n, max(c, it->c))),
				D[0][it->n].n = n,
				D[0][it->n].c = it->c;
	}
	for (int i = 2; i <= N; ++i)
		L[D[0][i].n].push_back(i);
}

void DFS(int n = 1, int lv = 1){
	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();
	DFS();

	/* 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);
		printf("%d\n", max(find_dist(x, node), find_dist(y, node)));
	}

	return 0;
}