Cod sursa(job #223438)

Utilizator CezarMocanCezar Mocan CezarMocan Data 28 noiembrie 2008 16:57:31
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.46 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define MAXN 30100
#define MAX_N 30100
#define INF 2000000000

using namespace std;

struct muchie {
	int a, b, c;
};

int n, m, k, i, j, x, y, lc, max1, max2;
int par[MAXN], p[MAXN], e[MAX_N], niv[MAX_N], level[MAXN], viz[MAXN], rmq[MAX_N][20];
int pp1[MAXN], pp2[MAXN], pp[MAXN], p2[30], csp[MAXN];
int dnk[MAXN][20], mx[MAXN][20];
muchie t[MAXN];
vector <int> v[MAXN], cs[MAXN];

inline int min(int a, int b) {
    if (a < b) 	return a;
    else 		return b;    
}

inline int max(int a, int b) {
    if (a > b) 	return a;
    else 		return b;    
}


bool cmp(muchie x, muchie y) {
	if (x.c < y.c)
		return true;
	else
		return false;
}

bool dif_comp(int x, int y) {
	int p1 = x, p2 = y;
	while (par[p1] != p1)
		p1 = par[p1];
	while (par[p2] != p2) 
		p2 = par[p2];
	
	if (p1 != p2) 	return true;
	else 			return false;
}

void merge_comp(int x, int y) {
	int p1 = x, p2 = y, ant, pp;
	
	while (par[p1] != p1) 
		p1 = par[p1];
	pp = p1;p1 = x;
	while (par[p1] != pp) {
		ant = p1;
		p1 = par[p1];
		par[ant] = pp;
	}
	while (par[p2] != pp) {
		ant = p2;
		p2 = par[p2];
		par[ant] = pp;
	}
	
	
}

void APM() {
	int i, ant, p, pp;
	for (i = 1; i <= n; i++)
		par[i] = i;
	
	for (i = 1; i <= m; i++) {
		if (dif_comp(t[i].a, t[i].b)) {
			v[t[i].a].push_back(t[i].b);
			cs[t[i].a].push_back(t[i].c);

			v[t[i].b].push_back(t[i].a);
			cs[t[i].b].push_back(t[i].c);
			
			merge_comp(t[i].a, t[i].b);
		}
	}
	
	for (i = 1; i <= n; i++) {
		p = par[i];
		while (p != par[p])
			p = par[p];
		pp = p;
		
		p = i;
		while (p != par[p]) {
			ant = p;
			p = par[p];
			par[ant] = pp;
		}
	}
	
	for (i = 1; i <= n; i++)
		if (viz[par[i]] == 0) {
			v[par[i]].push_back(0);
			v[0].push_back(par[i]);
			cs[0].push_back(0);
			cs[par[i]].push_back(0);
			viz[par[i]] = 1;
		}
	
	for (i = 1; i <=m; i++)
		if (par[i] == i)
			par[i] = 0;
	memset(viz, 0, sizeof(viz));
}

void euler(int nod, int lvl) {
	int i;
	e[0]++; e[e[0]] = nod;
	level[nod] = lvl; niv[e[0]] = lvl;
	viz[nod] = 1;
	
	for (i = 0; i < v[nod].size(); i++) {
		if (viz[v[nod][i]] == 0) {
			p[v[nod][i]] = nod;
			csp[v[nod][i]] = cs[nod][i];
			euler(v[nod][i], lvl + 1);
			e[0]++;
			e[e[0]] = nod; niv[e[0]] = lvl;
		}
	}
}

void build_rmq() {
	int i, j;
	for (i = 1; i <= e[0]; i++)
		rmq[i][0] = i;
	
    for (j = 1; p2[j] <= e[0]; j++) 
        for (i = 1; i <= e[0]; i++) {
            rmq[i][j] = rmq[i][j - 1];
            if (niv[rmq[i][j]] > niv[rmq[i + p2[j-1]][j-1]]) 
                rmq[i][j] = rmq[i + p2[j-1]][j-1];   
        }	
}

void init_lca() {
    for (i = 1; i <= e[0]; i++) {
        if (pp1[e[i]] == 0)        
            pp1[e[i]] = i;
        pp2[e[i]] = i;
    }	
   pp[1] = 0;
    for (i = 2; i < MAXN; i++) 
        pp[i] = pp[i / 2] + 1;	
	for (i = 0; i <= 18; i++)
		p2[i] = 1 << i;
}

int lca(int a, int b) {
	
    int x, y, z, mn;
    x = min(pp1[a], pp1[b]);
    y = max(pp2[a], pp2[b]);
    
    z = y - x + 1;
    
    if (niv[rmq[x][pp[z]]] < niv[rmq[y-p2[pp[z]]+1][pp[z]]] ) 
        mn = rmq[x][pp[z]];        
    else
        mn = rmq[y-p2[pp[z]]+1][pp[z]];
        
    return e[mn];
}

void init_dinamica() {
	int i, j;
    for (i = 0; i <= n; i++) {
        dnk[i][0] = p[i];
        mx[i][0] = csp[i];
    }
    
    for (i = 0; i <= n; i++)
        for (j = 1; (1 << j) <= n; j++) {
            dnk[i][j] = dnk[dnk[i][j-1]][j-1];
            mx[i][j] = max(mx[dnk[i][j-1]][j-1], mx[i][j-1]);    
        }	
}

int det_max(int p, int q) {
    int maxim, t, pp, qq;
    maxim = 0;
    qq = p;
    pp = level[p] - level[q];   
    while (pp && qq) {
        t = 0;
        while (1 << (t + 1) < pp)         
            ++t;
        if (mx[qq][t] > maxim)
            maxim = mx[qq][t];
        qq = dnk[qq][t];
        pp -= (1 << t); 
    }
    return maxim;	
}

int main() {
	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", &t[i].a, &t[i].b, &t[i].c);
	
	
	sort(t + 1, t + m + 1, cmp);
	
	APM();
	
	viz[0] = 1;
	euler(0, 1);
	
	init_lca();	
	build_rmq();
	init_dinamica();
	
	for (i = 1; i <= k; i++) {
		scanf("%d%d", &x, &y);
		lc = lca(x, y);
		
		max1 = det_max(x, lc);
		max2 = det_max(y, lc);
		
		printf("%d\n", max(max1, max2));
	}
		
	return 0;
}