cunionset.h

来自「一个基于启发式算法的搬运工求解程序」· C头文件 代码 · 共 94 行

H
94
字号
#pragma once
#include <map>
using namespace std;

template<class T>
class CUnionSet
{
public:
	CUnionSet(): size(0) {}
	void MakeSet(T k);
	void JoinSet(T x, T y);		
	bool Together(T x, T y);	
	int  SetSize(T x);			//包含了x的这个部分所含有元素的个数
	int  Size();				//该并查集分成了几个部分
	void Clear();
protected:
	map<T, T> father;
	map<T, int> rank;
private:	    
	T FindRoot(T x);
	int size;
};

template<class T>
void CUnionSet<T>::Clear()
{
	father.clear();
	rank.clear();
	size = 0;
}

template<class T>
void CUnionSet<T>::MakeSet(T k)
{
	if(rank[k] == 1)
		return;
	father[k] = k;
	rank[k] = 1;
	size++;
}

template<class T>
void CUnionSet<T>::JoinSet(T x, T y)
{
	//必须保证x, y都已经存在
	T XX = FindRoot(x);
	T YY = FindRoot(y);

	if(XX == YY)
		return;

	//we need not update the value of rank[yy] or rand[xx];
	if(rank[XX] > rank[YY])	
	{
		father[YY] = XX;
		rank[XX] += rank[YY];		
	}
	else
	{
		father[XX] = YY;
		rank[YY] += rank[XX];		
	}
	size--;
}

template<class T>
T CUnionSet<T>::FindRoot(T x )
{
	/*
		可能会存在异常。map[x],假如x本身就不存在,它会返回0值,
		但是这个0值不能和已经存在的0值区分开
	*/
	while(x != father[x])
		 x = father[x];
	return x;	
}

template<class T>
int CUnionSet<T>::Size()
{		 
	return size;
}

template<class T>
bool CUnionSet<T>::Together(T x, T y)
{
	return FindRoot(x) == FindRoot(y);
}

template<class T>
int CUnionSet<T>::SetSize(T x)
{
	return rank[FindRoot(x)];
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?