并差集,顾名思义是关于集合的查找与合并的操作
常用的实现方法有数组,链表,树这三种,虽然方法不同,但是大概思想应该是相同的
我们在什么时候使用并差集
个人认为并差集的使用应该是在题目要求关系点很多并且判断两点或多点是否有某种关系时
例如杭电的 畅通工程 就是给你几行数据,每行数据有两个整数a,b表示a,b之间有路,然后最后一行给你两个点让你判断这两点是否连通
如果用一般的方法就是把路都存下来然后使用图把所有连通点记录,看两点是否连通时间复杂度O(n^2)
并差集的算法则是将所有相连的点看作一个集合,记录完成后查询两点是否在同一集合即可
操作的实现就是首先每个点的上级是他本身然后将连通的两点其中一个作为根节点即可然后继续向下进行直到数据全部记录最后判断两点是否在同一集合即可
当然判断两点是否在同一集合首先要找到这两点各自的根节点再判断根节点是否相同即可
int find(int x) //寻找根节点
{
int r=x;
while (pre[r]!=r) //找到的上级不是根节点
r=pre[r] ; //继续向上找
return r ; //找到根节点
}
两点连通,意味着两点所在集合是一个集合
void join(int x,int y)
{
int fx=find(x),fy=find(y); //找这两个点的根节点
if(fx!=fy) //判断根节点是否相同
pre[fx]=fy; //不同就将两点所在集合合并,操作起来就是将其中一个根节点连到另一个上
}
还有一个路径压缩
int find(int x) //查找根节点
{
int r=x;
while ( pre[r ] != r ) //返回根节点 r
r=pre[r ];
int i=x , j ;
while( i != r ) //将根节点变成自己的直属上级 //路径压缩
{
j = pre[ i ]; // 在改变上级之前用临时变量 j 记录下他的值
pre[ i ]= r ; //把上级改为根节点
i=j;
}
return r ;
}