Cod sursa(job #443118)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 16 aprilie 2010 02:27:38
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <iostream>
#include <fstream>

using namespace std;

typedef unsigned long ulong;
typedef unsigned int uint;

class UnionFind
{
	public:
		UnionFind(ulong nElements)
			:	parent(new ulong[nElements + 1]), 
				height(new ulong[nElements + 1]), 
				numElements(nElements)
		{
			for(uint i = 1; i <= numElements; i++)
			{
				parent[i] = i;
				height[i] = 1;
			}
		}
		
		~UnionFind()
		{
			delete [] parent;
			delete [] height;
		}
		
	public:
		/**
		 * 	Assuming x and y are in different sets, this method will union 
		 *	these two sets together.
		 */
		void unionSets(ulong x, ulong y)
		{
			ulong rootX = getRoot(x), rootY = getRoot(y);
			
			if(height[rootX] < height[rootY])
			{
				parent[rootX] = rootY;
			}
			else if(height[rootY] < height[rootX])
			{
				parent[rootY] = rootX;
			}
			else
			{
				parent[rootY] = rootX;
				height[rootX] += 1;
			}
			
		}
		
		/**
		 * 	Returns true if x and y are in the same set, and false otherwise.
		 */
		bool sameSets(ulong x, ulong y)
		{
			return getRoot(x) == getRoot(y);
		}
	
	private:
		ulong getRoot(ulong node)
		{
			ulong root = parent[node];
			
			while(root != parent[root])
				root = parent[root];
				
			return root;
		}
	
	private:
		ulong * parent;
		ulong * height;
		ulong numElements;
};

int main(int argc, char * argv[]) 
{
	
	const char * inFile = "disjoint.in";
	const char * outFile = "disjoint.out";
	
	ifstream fin(inFile);
	ofstream fout(outFile);
	
	#ifndef NDEBUG
		if(!fin || !fout)
		{
			cerr << "Error opening one of \"" << inFile << "\" or \"" << outFile << "\"" << endl;
			return -1;
		}
	#endif
	
	/**
	 *	Read the data in.
	 */
	ulong numElements, numOps;
	fin >> numElements >> numOps;
	
	/**
	 *	Solve the problem.
	 */
	UnionFind unionFind(numElements);
	
	ulong opCode, x, y;
	for(ulong i = 0; i < numOps; i++)
	{
		fin >> opCode >> x >> y;
		
		switch(opCode)
		{
			case 1:
				unionFind.unionSets(x, y);
				break;
			
			case 2:
				fout << ((unionFind.sameSets(x, y)) ? "DA" : "NU") << "\n";
				break;
		}
	}
	
	/**
	 *	Cleanup!
	 */
	fout.close();
	fin.close();
	
	return 0;
}