Cod sursa(job #1760169)

Utilizator andreioneaAndrei Onea andreionea Data 20 septembrie 2016 13:58:42
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <list>
#include <unordered_map>
#include <utility>

struct file_manip {

	std::ifstream fin;
	std::ofstream fout;

	file_manip(const char* filename) {
		std::string infilename  = std::string(filename) + ".in";
		std::string outfilename = std::string(filename) + ".out";
		fin.open(infilename.c_str());
		fout.open(outfilename.c_str());
	}

	template <class T>
	file_manip& operator << (const T& rhs) {
		fout << rhs;
		return *this;
	}
	template <class T>
	file_manip& operator >> (T& rhs) {
		fin >> rhs;
		return *this;
	}
};
struct DS
{
	std::unordered_map<int, std::list<int>> forrest;
	std::vector<int> indices;
	DS(int N)
	{
		indices.reserve(N+1);
		int x = 0;
		std::generate_n(indices.begin(), N + 1, [&x]() { return x++;});
		x = 1;
		for (x = 1; x <= N; ++x)
		{
			std::list<int> s{x};
			forrest[x] = s;
		}
	}
	void Associate(int x, int y)
	{
		const auto id1 = indices[x];
		const auto id2 = indices[y];
		if (id1 == id2)
			return;
		auto& s1 = forrest[id1];
		auto& s2 = forrest[id2];
		if (s1.size() < s2.size())
		{
			std::list<int> ss2;
			ss2.swap(forrest[id2]);
			forrest.erase(id2);
			auto& s1 = forrest[id1];
			for (const auto i : ss2){
				indices[i] = id1;
				s1.push_back(i);
			}
		}
		else
		{
			std::list<int> ss1;
			ss1.swap(forrest[id1]);
			forrest.erase(id1);
			
			for (const auto i : ss1){
				indices[i] = id2;
				s2.push_back(i);
			}	
		}
	}
	bool AreTheSame(int x, int y) const
	{
		return indices[x] == indices[y];
	}
};
int main()
{
	file_manip fm("disjoint");
	int N, M, op, x, y;
	fm >> N >> M;
	DS ds(N);
	while (M--)
	{
		fm >> op >> x >> y;
		if (op == 1){
			ds.Associate(x,y);
		}
		else {
			if (ds.AreTheSame(x,y))
			{
				fm << "DA\n";
			}
			else
			{
				fm << "NU\n";
			}
		}
	}
	return 0;
}