算法基础-并查集

并查集基础

蒟蒻的新手博客···

并查集是可以用来解决联通块问题的,首先,列举一个例子:

现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。

规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

然后,我给出N对关系,然后,要求输入两个人,判断有没有亲戚关系,并用代码实现,先思考一下

题目链接:https://www.luogu.com.cn/problem/P1551

 

 

 

那么,改如何实现呢,首先,不用说,先用数组存起来,试想一下:

如果有一对亲戚关系1,2,那么可以用f[1] = 2 表示

那么多对关系是不是可以这么表示:

1 1 3 3 5 6

1 2 3 4 5 6

1和2是亲戚关系,那么f[1]就会等于f[2];而且明显,3和4也是满足亲戚关系的。那么 在每次输入亲戚关系时,是不是可以这么做。

但是,如果现在又给出了1和4是亲戚关系,该怎么办,f[4]已经等于f[3]了。

其实当1和4连接起来时,1,2,3,4全连接起来了,那么就可以先判断该点的数组值是否等于自己的下标,如果不等于,则存在关系,然后就继续找,直到找到最后,下标等于该点对应的值时,在把该点的值改为需要插入的下标就行了。

当需要查找两点是否存在亲戚关系时,通过在find里面一直找,直到找到最后,若两点找到最后的点都相同的话,则即可证明两点存在亲戚关系。

代码如下:

 1 int fa[maxn];//也可以使用一些stl来优化,比如map<int ,int >fa,这样可以k掉更多样例,题目。
 2 int find(int x)//查找
 3 {
 4     if(x==fa[x]) return x;
 5     return fa[x]=find(fa[x]);
 6 }
 7 void join(int c1,int c2)//插入
 8 {
 9     int f1=find(c1),f2=find(c2);
10     if(f1!=f2) fa[f1]=f2;
11 }

 

若觉得写的不好,见谅,毕竟第一次写   0.0

posted @ 2020-03-27 07:27  darker_wxl  阅读(76)  评论(0编辑  收藏  举报
window.onload = function(){ $("#live2dcanvas").attr("style","position: fixed; opacity: 0.7; left: 70px; bottom: 0px; z-index: 1; pointer-events: none;") }