并查集基础
蒟蒻的新手博客···
并查集是可以用来解决联通块问题的,首先,列举一个例子:
现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。
规定: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