zoukankan      html  css  js  c++  java
  • 算法基础-并查集

    并查集基础

    蒟蒻的新手博客···

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

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

    规定: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

  • 相关阅读:
    小村系列之十八:幸福的桥
    小村系列之十六:改革的石头
    获取<select>,<radio>,<checkbox>中未被选中的value值和被选中的value值
    display:inline-block,block,inline的区别与用法
    Java中List Set Map集合的遍历
    C#自定义List类
    C#获取文件和文件夹大小
    C# winform带进度条的图片下载
    C#委托的详细使用
    asp.net cookie和session的详细使用
  • 原文地址:https://www.cnblogs.com/darker-wxl/p/12579014.html
Copyright © 2011-2022 走看看