Cod sursa(job #2507009)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 decembrie 2019 12:47:26
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.03 kb
//ALEX ENACHE

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>

using namespace std;

//-----------------------------------------------------------------

#include <fstream>

//ifstream cin("input"); ofstream cout("output");
ifstream cin("radiatie.in"); ofstream cout("radiatie.out");

const int MAXN = 30100;
const int inf = 1e9;
const int MAXLOG = 16;

struct edge {
	int a, b, val;
};
bool cmp(edge a, edge b) {
	return a.val < b.val;
}

int LOG[MAXN];

int n, m, k;
edge ord[MAXN];

int dad[MAXN];
int card[MAXN];

vector < pair < int , int > > gr[MAXN];
int str[MAXLOG][MAXN];
int MAX[MAXLOG][MAXN];

int used[MAXN];
int lv[MAXN];


void read() {
	cin >> n >> m >> k;
	for (int i = 1; i <= m; i++) {
		cin >> ord[i].a >> ord[i].b >> ord[i].val;
	}
}

void make_log() {
	for (int i = 2; i <= n; i++) {
		LOG[i] = LOG[i / 2] + 1;
	}
}

int superdad(int nod) {
	if (dad[nod] != nod) {
		dad[nod] = superdad(dad[nod]);
	}
	return dad[nod];
}

void unite(int a, int b) {
	if (card[a] < card[b]) {
		swap(b, a);
	}
	card[a] += card[b];
	card[b] = 0;
	dad[b] = a;
}

void make_apm() {
	for (int i = 1; i <= m; i++) {
		superdad(ord[i].a);
		superdad(ord[i].b);
		if (dad[ord[i].a] != dad[ord[i].b]) {
			unite(dad[ord[i].a], dad[ord[i].b]);
			gr[ord[i].a].push_back({ ord[i].b , ord[i].val });
			gr[ord[i].b].push_back({ ord[i].a , ord[i].val });
		}
	}
}

void dfs(int nod) {
	used[nod] = 1;
	for (auto& x : gr[nod]) {
		if (!used[x.first]) {
			str[0][x.first] = nod;
			MAX[0][x.first] = x.second;
			lv[x.first] = lv[nod] + 1;
			dfs(x.first);
		}
	}
}

void make_stramosi() {
	dfs(1);
	for (int bit = 1; bit <= LOG[n]; bit++) {
		for (int i = 1; i <= n; i++) {
			str[bit][i] = str[bit - 1][str[bit - 1][i]];
			MAX[bit][i] = max(MAX[bit - 1][i], MAX[bit - 1][str[bit - 1][i]]);
		}
	}
}

int ans;

int ridic_b(int &nod , int nr) {
	while (nr) {
		ans = max(ans, MAX[LOG[nr]][nod]);
		nod = str[LOG[nr]][nod];
		nr -= (1 << LOG[nr]);
	}
	return nod;
}

void ridic_a_b(int &a, int &b) {
	for (int bit = LOG[n]; bit >= 0; bit--) {
		if (str[bit][a] != str[bit][b]) {
			ans = max(ans, MAX[bit][a]);
			ans = max(ans, MAX[bit][b]);
			a = str[bit][a];
			b = str[bit][b];
		}
	}
}

void query(int a , int b) {
	
	if (lv[a] > lv[b]) {
		swap(a, b);
	}

	ans = 0;

	ridic_b(b , lv[b] - lv[a]);

	ridic_a_b(a, b);

	if (a != b) {
		ans = max(ans, MAX[0][a]);
		ans = max(ans, MAX[0][b]);
	}

}

void solve() {

	read();

	make_log();

	sort(ord + 1, ord + m + 1, cmp);
	for (int i = 1; i <= n; i++) {
		dad[i] = i;
		card[i] = 1;
	}

	make_apm();

	make_stramosi();

	for (int i = 1; i <= k; i++) {
		int a, b;
		cin >> a >> b;	
		query(a, b);
		cout << ans << '\n';
	}


}

int main() {

	solve();

	return 0;
}