Cod sursa(job #975494)

Utilizator tudorv96Tudor Varan tudorv96 Data 20 iulie 2013 14:12:38
Problema Radiatie Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <fstream>
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
using namespace std;

ifstream fin ("radiatie.in");
ofstream fout ("radiatie.out");

#define last (int)(E.size()-1)
#define pb push_back

typedef pair <int, int> M;
typedef pair <int, M> CM;

vector <list <pair <int, int> > > g;
vector <vector <int> > rmq, dmin, t;
vector <CM> muchii;
vector <int> T, tata, F, E, L, bp, v;
vector <bool> viz;
int n, m, q;

int cmp(int a, int b) {
	return ((L[a] < L[b]) ? a : b);
}

void dfs(int x, int val) {
	E.pb(x); L.pb(val);
	F[x] = last;
	viz[x] = 1;
	for (list <M> :: iterator it = g[x].begin(); it != g[x].end(); ++it)
		if (!viz[(*it).first]) {
			v[(*it).first] = (*it).second;
			tata[(*it).first] = x;
			dfs((*it).first, val + 1);
			E.pb(x); L.pb(val);
		}
}

void RMQ() {
	bp.resize(last + 1);
	for (int i = 2; i <= last; ++i)
		bp[i] = bp[i >> 1] + 1;
	rmq.resize(bp[last] + 1);
	dmin.resize(bp[n] + 1);
	t.resize(bp[n] + 1);
	for (int i = 0; i <= bp[last]; ++i) {
		if (i <= bp[n]) {
			dmin[i].resize(n+1);
			t[i].resize(n+1);
			for (int j = 1; j <= n; ++j) {
				t[i][j] = !i ? tata[j] : t[i-1][t[i-1][j]];
				dmin[i][j] = !i ? v[j] : max(dmin[i-1][j], dmin[i-1][t[i-1][j]]);
			}
		}
		rmq[i].resize(last+1);
		if (!i)
			for (int j = 1; j <= last; ++j)
				rmq[0][j] = j;
		else
			for (int j = 1 ; j <= last - (1 << i) + 1; ++j)
				rmq[i][j] = cmp (rmq[i-1][j], rmq[i-1][j + (1 << (i - 1))]);
	}
}

int LCA(int x, int y) {
	int a = F[x], b = F[y];
	if (a > b)
		swap (a, b);
	int pow = bp[b - a + 1];
	return E[cmp(rmq[pow][a], rmq[pow][b + 1 - (1 << pow)])];
}

int query(int x, int y) {
	int dif = L[F[x]] - L[F[y]], res = 0;
	for (int i = 0; i <= bp[dif]; ++i)
		if ((1 << i) & dif) {
			res = max(dmin[i][x], res);
			x = t[i][x];
		}
	return res;
}

int find(int x) {
	if (T[x] != x)
		T[x] = find(T[x]);
	return T[x];
}

void unite(int x, int y) {
	tata[find (max(x, y))] = find (min (x, y));
}

void Resizeall() {
	muchii.reserve(m+1);
	g.resize(n+1);
	T.resize(n+1); tata.resize(n+1);
	E.reserve(2*n+10), L.reserve(2*n+10);
	E.pb(0), L.pb(0);
	F.resize(n+1);
	v.resize(n+1);
	viz.resize(n+1);
	for (int i = 1; i <= n; ++i)
		T[i] = i;
}	

int main() {
	fin >> n >> m >> q;
	Resizeall();
	while (m--) {
		int x, y, c;
		fin >> x >> y >> c;
		muchii.pb(CM (c, M (x,y)));
	}
	sort (muchii.begin(), muchii.end());
	int apm = 1;
	for (vector <CM> :: iterator it = muchii.begin(); apm < n && it != muchii.end(); ++it)
		if (find((*it).second.first) != find((*it).second.second)) {
			unite ((*it).second.first, (*it).second.second);
			apm++;
			g[(*it).second.first].pb(M ((*it).second.second, (*it).first));
			g[(*it).second.second].pb(M ((*it).second.first, (*it).first));
		}
	vector <CM>().swap(muchii);
	dfs(1, 0);
	RMQ();
	while (q--) {
		int x, y, z = 0, lca;
		fin >> x >> y;
		lca = LCA(x, y);
		z = max(z, query(x, lca));
		z = max(z, query(y, lca));
		fout << z << "\n";
	}
}