Cod sursa(job #218856)

Utilizator andrei.12Andrei Parvu andrei.12 Data 3 noiembrie 2008 20:03:18
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include<stdio.h>
#include<vector>
#include<set>
#include<algorithm>

using namespace std;

#define x first
#define y second
#define lg 15001

int n, m, k, i, j, cnt[lg], h[lg], rsp[lg], tata[lg], x, y, ind, adn[lg], pt[21], poz[lg], lca, p1, p2;
bool fst[lg];

pair<int, pair<int, int> > v[lg];
pair<int, int> lst[18][2*lg], d[18][lg];
vector< pair<int, int> > w[lg];

void adg(int x, int y){
	if (x == y)
		return ;
	w[v[i].y.x].push_back(make_pair(v[i].y.y, v[i].x));
	w[v[i].y.y].push_back(make_pair(v[i].y.x, v[i].x));

	if (h[x] < h[y])
		tata[x] = y, cnt[y] += cnt[x];
	else{
		if (h[x] == h[y])
			h[x] ++;
		tata[y] = x, cnt[x] += cnt[y];
	}
}
int find(int x){
	int r = x;

	for (; tata[r]; r = tata[r]);
	while (tata[x]){
		int k = tata[x];
		tata[x] = r;
		x = k;
	}

	return r;
}
void df(int nod, int ad){
	fst[nod] = 1;
	lst[0][++ ind].x = ad, lst[0][ind].y = nod; adn[nod] = ad; poz[nod] = ind;

	for (int i = 0; i < (int)w[nod].size(); i ++)
		if (!fst[w[nod][i].x]){
			df(w[nod][i].x, ad + 1);
			lst[0][++ ind].x = ad, lst[0][ind].y = nod;

			d[0][w[nod][i].x].x = w[nod][i].y;
			d[0][w[nod][i].x].y = nod;
		}
}
int caut(int poz, int nr){
	int r = 0;
	while (nr > 0){
		int i;
		for (i = 0; pt[i] <= nr; i ++); i --;
	
		r = max(r, d[i][poz].x);
		nr -= pt[i]; poz = d[i][poz].y;
	}

	return r;
}

int main()
{
	freopen("radiatie.in", "rt", stdin);
	freopen("radiatie.out", "wt", stdout);

	scanf("%d%d%d", &n, &m, &k);
	for (i = 1; i <= m; i ++)
		scanf("%d%d%d", &v[i].y.x, &v[i].y.y, &v[i].x);
	for (i = 1; i <= n; i ++)
		cnt[i] = 1;

	sort(v+1, v+m+1);

	for (i = 1; i <= m; i ++){
		adg(find(v[i].y.x), find(v[i].y.y));
		
//	        printf("%d\n", cnt[find(1)]);	
		if (cnt[find(1)] == n)
			break;
	}
//	printf("%d\n", i);

	df(1, 0);

	pt[0] = 1;
	for (i = 1; i <= 20; i ++)
		pt[i] = 2*pt[i-1];

	for (i = 1; i <= 17; i ++){
		for (j = 1; j + pt[i-1] <= ind; j ++)
			if (lst[i-1][j].x <= lst[i-1][j + pt[i-1]].x)
				lst[i][j] = lst[i-1][j];
			else
				lst[i][j] = lst[i-1][j + pt[i-1]];
		for (j = 1; j <= n; j ++){
			d[i][j].y = d[i-1][d[i-1][j].y].y;
			if (d[i-1][j].x > d[i-1][d[i-1][j].y].x)
				d[i][j].x = d[i-1][j].x;
			else
				d[i][j].x = d[i-1][d[i-1][j].y].x;
		}
	}

	for (i = 1; i <= k; i ++){
		scanf("%d%d", &x, &y);
		
		p1 = poz[x], p2 = poz[y];
		if (p1 > p2)
			swap(p1, p2);

		for (j = 0; pt[j] <= p2 - p1 + 1; j ++); j --;

		if (lst[j][p1].x < lst[j][p2 - pt[j] + 1].x)
			lca = lst[j][p1].y;
		else
			lca = lst[j][p2 - pt[j] + 1].y;
//		printf("%d %d  %d\n", x, y, lca);

		printf("%d\n", max(caut(x, adn[x] - adn[lca]), caut(y, adn[y] - adn[lca])));
	}

	return 0;
}