并查集:并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示。
这是我百度的关于并查集的定义,在我看来并查集是把一些有关系的元素放到一个集合,这样我们就可以判断任意元素间的关系。
这样我们就可以先利用已知的关系创建并查集,然后判断元素间的关系。例如有的题就会给你一堆已知关系,a和b是亲戚,b和c是亲戚,d和f是亲戚…让你判断随意给出的两个人存不存在亲戚关系。
当关系网比较庞大时我们人为比较难判断,用并查集就很好解决。
创建并查集我们需要先创建一个和节点数数量一致的数组,数组parent[],数组表示下标对应的节点的根为哪个节点。
如:
并查集主要有两种操作:1,查找
2,合并
查找是为了找到操作节点的根,合并是把两个节点或和他们有关的节点放到一个集合。
首先先初始化一个数组:
int parent[max_size]
for(int i=1;i<=max_size;i++)//初始化 节点的父亲
{
parent[i]=-1;//把节点的根都设为-1
}
查找根
int find_root(int v)//传入需要查找根的节点
{
if(parent[v]==-1) return v;//若没有给他传入根,则它的根就是它本身
else
{
parent[v]=find_root(parent[v]);//压缩找父节点的路径
return parent[v];
}
}
合并:
int union(int x,int y)
{
int x_root,y_root;
x_root=find(x);
y_root=find(y);
if(x_root!=y_root)//要合并的两个节点不在同一集合,可以进行合并
{
parent[x_root]=y_root;//把其中一个节点的根设为另一个节点的根,即完成了合并操作。
return 1;//表示合并成功
}
else//要合并的两个节点在同一集合,不能进行合并,这里可以用来判断节点间是否形成了环
{
return 0;
}
}
这样的图就形成了环
而这样的就没有环
我们在导入已知关系时,可以用union(),检查某两点间是否形成了环也是union这两点,若合并失败说明形成了环。