Cod sursa(job #880326)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 16 februarie 2013 16:58:27
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

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

const int N = 17100;
const int M = 31000;

int n, m, k, pa[N], a[M], nr, b[M], c[M], p[M], niv[N], rmq[19][3 * N], cs[N], st[19][N], smax[19][N], p2[3 * N];
vector<int> v[N], arb[N];
bool ver[N];

bool cmp(int a, int b) {
	return c[a] < c[b];
}

int rad(int nod) {
	if(!pa[nod])
		return nod;
	return pa[nod] = rad(pa[nod]);
}

void makeapm() {
	int i;
	
	sort(p + 1, p + n + 1, cmp);
	
	for(i = 1; i<=m; ++i) {
		int r1 = rad(a[p[i]]), r2 = rad(b[p[i]]);
		
		if(r1 != r2) {
			arb[a[p[i]]].push_back(p[i]);
			arb[b[p[i]]].push_back(p[i]);
			pa[r1] = r2;
		}
	}
}

int oth(int nod, int nrm) {
	return nod ^ a[nrm] ^ b[nrm];
}

void linarb(int nod) {
	ver[nod] = 1;
	
	cs[nod] = ++nr;
	rmq[0][nr] = niv[nod];
	
	for(vector<int>::iterator it = arb[nod].begin(); it != arb[nod].end(); ++it) {
		int fiu = oth(nod, *it);
		
		if(ver[fiu])
			continue;
		
		niv[fiu] = niv[nod] + 1;
		
		rmq[0][++nr] = niv[nod];
		linarb(fiu);
	}
}

void makeLCA() {
	int i, j;
	
	for(i = 1; i<=n; ++i) if(!ver[i])
		linarb(i);
	
	for(i = 1; (1<<i) <= nr; ++i)
		for(j = 1; j <= nr - (1<<i) + 1; ++j)
			rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1<<(i - 1))]);
}

int LCA(int nod1, int nod2) {
	if(cs[nod1] > cs[nod2])
		swap(nod1, nod2);
	int l = p2[cs[nod2] - cs[nod1]];
	
	return min(rmq[l][cs[nod1]], rmq[l][cs[nod2] - (1<<l) + 1]);
}

void df(int nod) {
	ver[nod] = 1;
	
	for(vector<int>::iterator it = arb[nod].begin(); it != arb[nod].end(); ++it) {
		int fiu = oth(nod, *it);
		if(ver[fiu])
			continue;
		smax[0][fiu] = c[*it];
		st[0][fiu] = nod;
	
		df(fiu);
	}
}

void str() {
	int i, j;
	for(i = 1; i<=n; ++i)
		ver[i] = 0;
	
	for(i = 1; i <= n; ++i) if(!ver[i])
		df(i);
	for(i = 1; (1<<i) <= n; ++i)
		for(j = 1; j<=n; ++j) {
			
			if(smax[i - 1][j] > smax[i - 1][st[i - 1][j]]) {
				st[i][j] = st[i - 1][j];
				smax[i][j] = smax[i - 1][j];
			}
			else {
				st[i][j] = st[i - 1][st[i - 1][j]];
				smax[i][j] = smax[i - 1][st[i - 1][j]];
			}
		}
}

int main() {
	int i, nod1, nod2, rez, j;
	
	in >> n >> m >> k;
	
	for(i = 1; i<=m; ++i) {
		in>> a[i] >> b[i] >> c[i];
		p[i] = i;
		v[a[i]].push_back(i);
		v[b[i]].push_back(i);
	}
	
	makeapm();
	
	makeLCA();
	
	str();
	
	for(i = 2; i < 3 * N; ++i)
		p2[i] = p2[i/2] + 1;
	
	for(i = 1; i <= k; ++i) {
		in >> nod1 >> nod2;
		
		int nivlca = LCA(nod1, nod2);
		
		rez = 0;
		for(j = 19; j>=0; --j) {
			if(niv[nod1] - (1<<j) >= nivlca) {
				rez = max(rez, smax[j][nod1]);
				nod1 = st[j][nod1];
			}
			if(niv[nod2] - (1<<j) >= nivlca) {
				rez = max(rez, smax[j][nod2]);
				nod2 = st[j][nod2];
			}
		}
		out << rez << "\n";
	}
	
	return 0;
}