Cod sursa(job #424868)

Utilizator runnaway90Oprescu Radu Constantin runnaway90 Data 25 martie 2010 11:56:20
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include<stdio.h>
#include<vector>
#include<algorithm>

using namespace std;

#define N 16000
#define M 31000
#define pb push_back
#define mp make_pair

struct muchie{int x, y, z;} mu[M];

int n, m, k, lg, rad, lca, maxim, 
	tata[N], cost[N], eul[3*N], height[2*N], pozitia[N],
	mini[3*N][20], pozmini[3*N][20];
vector < pair<int, int> > fiu[N];


bool cmp(muchie a, muchie b){
	return (a.z < b.z);
}

void back(int nod, int h){
	if (fiu[nod].size()){
		eul[++lg] = nod; height[lg] = h; pozitia[nod] = lg; 
int i;		
		for (i = 0; i < fiu[nod].size(); i++){
			back(fiu[nod][i].first, h+1);
			eul[++lg] = nod; height[lg] = h; pozitia[nod] = lg;
		}
	}
	else
		eul[++lg] = nod, height[lg] = h, pozitia[nod] = lg;
}




void rmq(){
int i, j, q;
	for (i = 1; i <= lg; i++)
		mini[i][0] = height[i], pozmini[i][0] = i;
	
	for (j = 1, q = 2; q <= lg; q <<= 1, j++)
		for (i = 1; i <= lg; i++){
			mini[i][j] = mini[i][j-1]; pozmini[i][j] = pozmini[i][j-1];
			if (mini[i][j] > mini[i+(q>>1)][j-1]){
				mini[i][j] = mini[i+(q>>1)][j-1];
				pozmini[i][j] = pozmini[i+(q>>1)][j-1];
			}
		}
}

int main(){

int i;

	freopen("radiatie.in", "r", stdin);
	freopen("radiatie.out", "w", stdout);
	
	scanf("%d %d %d", &n, &m, &k);
	for(i = 1; i <= m; i++) scanf("%d %d %d", &mu[i].x, &mu[i].y, &mu[i].z);
	
	sort(mu+1, mu+m+1, cmp);
	
int x1, y1, r1, r2;

	for (i = 1; i <= m; i++){
		for (x1 = mu[i].x, r1 = 0; tata[x1] != 0; r1++, x1 = tata[x1]);
		for (y1 = mu[i].y, r2 = 0; tata[y1] != 0; r2++, y1 = tata[y1]);
		if (x1 != y1){
			if (r1 > r2){
				tata[y1] = x1; cost[y1] = mu[i].z;
				fiu[x1].pb(mp(y1,mu[i].z));
			}
			else{
				tata[x1] = y1; cost[x1] = mu[i].z;
				fiu[y1].pb(mp(x1,mu[i].z));
			}
		}
	}
	
	for (i = 1; i <= n; i++)
		if (!tata[i]) rad = i;
	
	lg = 0; 
	back(rad, 1);
/*
	for (i = 1; i <= n; i++)
		printf("tatal lui %d este %d\n", i, tata[i]);
	
	for (i = 1; i <= n; i++)
		printf("pozitia lui %d este %d\n", i, pozitia[i]);
	
	for (i = 1; i <= lg; i++)
		printf("%d ", eul[i]);
	
	printf("\n");
	for (i = 1; i <= lg; i++)
		printf("%d ", height[i]);
*/

	rmq();
int x2, y2, lung, q, j, aux; 
	for ( ; k; k--){
		scanf("%d %d", &x1, &y1);
		x2 = pozitia[x1]; y2 = pozitia[y1];
		if (x2 > y2) {aux = x2; x2 = y2; y2 = aux;}
		lung = y2 - x2 + 1;

		for (j = 0, q = 2; q <= lung; j++, q <<= 1);
		
		if (mini[x2][j] < mini[y2- (q>>1) + 1][j])
			lca = eul[pozmini[x2][j]];
		else
			lca = eul[pozmini[y2-(q>>1) + 1][j]];
		maxim = 0;
		for ( ;x1 != lca; x1 = tata[x1])
			if (cost[x1] > maxim) maxim = cost[x1];
		for ( ;y1 != lca; y1 = tata[y1])
			if (cost[y1] > maxim) maxim = cost[y1];
		
		printf("%d\n", maxim );
//		printf("%d\n", lca);
	}
	return 0; 
}