Cod sursa(job #1540259)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 2 decembrie 2015 15:43:30
Problema Radiatie Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.59 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

struct Edge{

	int x, y, cost;

	Edge(int x, int y, int cost) {
		this->x = x;
		this->y = y;
		this->cost = cost;
	}

	bool operator < (const Edge a) const {
		return cost < a.cost;
	}

};

vector<Edge> edges;
vector< vector< pair<int, int> > > graph;
vector<int> pmd, parent, costParent, level;
vector< vector<int> > ancestors, ancestorsCost;

int getRoot(int node) {

	int temp = node;
	while (pmd[node] > 0)
		node = pmd[node];

	swap(temp, node);

	while (node != temp) {
		pmd[node] = temp;
		node = pmd[node];
	}

	return temp;

}

void kruskal(vector<Edge> edges, int n, vector< vector< pair<int, int> > > &graph) {

	sort(edges.begin(), edges.end());

	pmd.clear();
	pmd.resize(n + 1, -1);

	for (unsigned int i = 0; i < edges.size(); ++i) {

		int x = edges[i].x;
		int y = edges[i].y;
		int cost = edges[i].cost;

		int rx = getRoot(x);
		int ry = getRoot(y);

		if (rx == ry)
			continue;

		if (pmd[rx] < pmd[ry]) {

			pmd[rx] += pmd[ry];
			pmd[ry] = rx;

		}
		else {

			pmd[ry] += pmd[rx];
			pmd[rx] = ry;

		}

		graph[x].push_back(make_pair(y, cost));
		graph[y].push_back(make_pair(x, cost));

	}

}

void dfs(int node, int par, int costPar, int lvl) {

	parent[node] = par;
	costParent[node] = costPar;
	level[node] = lvl;

	for (unsigned int i = 0; i < graph[node].size(); ++i) {

		int adj = graph[node][i].first;
		int cost = graph[node][i].second;

		if (adj == par)
			continue;

		dfs(adj, node, cost, lvl + 1);

	}

}

void compAncestors(int n, vector< vector<int> > &ancestors, vector< vector<int> > &ancestorsCost) {

	for (int i = 1; i <= n; ++i) {

		ancestors[0][i] = parent[i];
		ancestorsCost[0][i] = costParent[i];

	}
	for (int i = 1; (1 << i) <= n; ++i) {

		for (int j = 1; j <= n; ++j) {

			ancestors[i][j] = ancestors[i - 1][ancestors[i - 1][j]];
			ancestorsCost[i][j] = max(ancestorsCost[i - 1][ancestors[i - 1][j]], ancestorsCost[i - 1][j]);

		}

	}

}

int goUp(int &node, int lvl) {

	int ret = 0;
	for (int i = 16; i >= 0; --i) {

		if (level[node] - lvl >= (1 << i)) {

			ret = max(ret, ancestorsCost[i][node]);
			node = ancestors[i][node];

		}

	}

	return ret;

}

int query(int x, int y) {

	int ret = 0;
	for (int i = 16; i >= 0; --i) {

		if (ancestors[i][x] != ancestors[i][y]) {

			ret = max(ret, ancestorsCost[i][x]);
			ret = max(ret, ancestorsCost[i][y]);

			x = ancestors[i][x];
			y = ancestors[i][y];

		}

	}

	if (x != y) {
		ret = max(ret, ancestors[0][x]);
		ret = max(ret, ancestors[0][y]);
	}

	return ret;

}

int main() {

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

	int n, k, m;
	fin >> n >> m >> k;

	graph.resize(n + 1);

	for (int i = 1; i <= m; ++i) {

		int x, y, cost;
		fin >> x >> y >> cost;

		edges.push_back(Edge(x, y, cost));

	}

	kruskal(edges, n, graph);

	parent.resize(n + 1, 0);
	costParent.resize(n + 1, 0);
	level.resize(n + 1, 0);
	for (int i = 1; i <= n; ++i)
		if (level[i] == 0)
			dfs(i, 0, 0, 1);

	ancestors.resize(17, vector<int>(n + 1, 0));
	ancestorsCost.resize(17, vector<int>(n + 1, 0));
	compAncestors(n, ancestors, ancestorsCost);

	for (; k; --k) {

		int x, y;
		fin >> x >> y;

		int ans = 0;

		if (level[x] > level[y])
			ans = goUp(x, level[y]);
		else if (level[x] < level[y])
			ans = goUp(y, level[x]);
		
		ans = max(ans, query(x, y));

		fout << ans << '\n';

	}

	return 0;

}

//Trust me, I'm the Doctor!