算法: 并查集(union & find)
用途:等价类的处理,最后期限任务调度。
最近开始复习数据结构。
看的是《数据结构算法与应用-c++语言描述》。
第三章:数据描述
看到后面的等价类,想到了以前用的并查集。
发现以前对于UFSET的理解是比较浅薄的。
于是乎,在网上找了些资料,然后又在PKU上找了些题目来练习下。
网上提到了“食物链”这个典型的题目。
记得以前看了好多遍就是不怎么明白,今天看了一份报告是用向量来解释的,非常好,易于理解。
const int MAX_SIZE = 1002;
class CUFSet
{
public:
CUFSet(int size)
{
nSize = size;
for (int i = 0; i < nSize; i ++)
{
parent[i] = -1; // parent[i] 为负表示是根节点,同时它的绝对值表示已该节点为根的集合中的元素个数(上次比赛时竟然没想出来。。。。)
relation[i] = 0; // 用于处理向量关系
}
}
void init(int n)
{
for (int i = 0; i <= n; i ++)
{
parent[i] = -1;
relation[i] = 0;
}
}
int Find(int x);
void Union(int rootx, int rooty);
//
int getRelation(int x)
{
return relation[x];
}
private:
int parent[MAX_SIZE];
int relation[MAX_SIZE]; //the relation with the root node: 0 same, 1 different
int nSize;
};
int CUFSet::Find(int x)
{
if (parent[x] < 0)
{
return x;
}
int xParent = parent[x];
parent[x] = Find(parent[x]); //路径压缩
//relation[x] = (relation[x] + relation[xParent])%2; //路径压缩时跟新关系之
return parent[x];
}
void CUFSet::Union(int rootx, int rooty)
{
if (rootx == rooty)
{
return;
}
int tmp = parent[rootx] + parent[rooty]; //加权
if (parent[rootx] < parent[rooty])
{
parent[rooty] = rootx;
parent[rootx] = tmp;
}
else
{
parent[rootx] = rooty;
parent[rooty] = tmp;
}
}