Cod sursa(job #678786)

Utilizator feelshiftFeelshift feelshift Data 12 februarie 2012 13:30:13
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
// http://infoarena.ro/problema/radiatie
#include <fstream>
#include <cstring>
#include <set>
using namespace std;

const int oo = 0x3f3f3f3f;
const int MAXSIZE = 20001;

struct stuff { int from,to,cost; };

class comparison {
	public:
		bool operator() (stuff first,stuff second) {
			return (first.cost < second.cost);
		}
};

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

int nodes,edges,selectedEdges,voyages;
int treeRank[MAXSIZE];
int maxLength[MAXSIZE];
pair<int,int> father[MAXSIZE];
multiset<stuff,comparison> edgesSet;

void unite(stuff edge);
int find(int node);
int buildMaxLength(int node,int targetNode);

int main() {
	in >> nodes >> edges >> voyages;

	for(int i=1;i<=edges;i++) {
		stuff edge;
		in >> edge.from >> edge.to >> edge.cost;
		edgesSet.insert(edge);
	}

	multiset<stuff,comparison>::iterator end = edgesSet.end();
	for(multiset<stuff,comparison>::iterator it=edgesSet.begin();it!=end && selectedEdges != nodes - 1;++it)
		if(find(it->from) != find(it->to))
			unite(*it);

	int from,to;
	for(int i=1;i<=voyages;i++) {
		in >> from >> to;
		memset(maxLength,0,MAXSIZE*sizeof(int));

		/*int son = from;
		bool found = false;
		for(;father[from].first;from=father[from].first) {
			maxLength[father[from].first] = max(maxLength[father[son].first],father[from].second);
			if(father[from].first == to) {
				out << maxLength[father[from].first] << "\n";
				found = true;
				break;
			}
			son = from;
		}

		son = to;
		if(!found)
			for(;father[to].first;to=father[to].first) {
				if(maxLength[father[to].first]) {
					out << max(maxLength[father[to].first],maxLength[father[son].first]) << "\n";
					found = true;
					break;
				}

				maxLength[father[to].first] = max(maxLength[father[son].first],father[to].second);
				son = to;
			}

		if(!found)
			out << "Nu am gasit solutie!\n";*/

		int node = buildMaxLength(from,to);
		if(node == oo)
			node = buildMaxLength(to,from);

		out << maxLength[node] << "\n";
	}

	return (0);
}

void unite(stuff edge) {
	int fromRoot = find(edge.from);
	int toRoot = find(edge.to);

	//for(int i=1;i<=nodes;i++)
		//out << father[i].second << " ";
	//out << "\n";

	//out << "Edge: " << edge.from <<  " " << edge.to << " | ";
	if(treeRank[fromRoot] < treeRank[toRoot]) {
		//father[fromRoot] = toRoot;
		father[edge.from].first = edge.to;
		father[edge.from].second = edge.cost;
		//out << edge.from << "->" << edge.to << " (" << edge.cost << ")\n\n";
	}
	else {
		//father[toRoot] = fromRoot;
		father[edge.to].first = edge.from;
		father[edge.to].second = edge.cost;
		//out << edge.to << "->" << edge.from << " (" << edge.cost << ")\n\n";
	}

	if(treeRank[fromRoot] == treeRank[toRoot])
		treeRank[fromRoot]++;

	selectedEdges++;
}

int find(int node) {
	if(!father[node].first)
		return node;
	else
		return find(father[node].first);
}

int buildMaxLength(int node,int targetNode) {
	//out << "Exploring node " << node << "\n";
	if(maxLength[father[node].first]) {
		maxLength[father[node].first] = max(maxLength[father[node].first],father[node].second);
		maxLength[father[node].first] = max(maxLength[father[node].first],maxLength[node]);
		return father[node].first;
	}

	maxLength[father[node].first] = max(maxLength[node],father[node].second);

	if(father[node].first == targetNode)
		return father[node].first;

	if(father[father[node].first].first)
		return buildMaxLength(father[node].first,targetNode);

	return oo;
}