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

  • 相关阅读:
    [BZOJ3413]匹配
    [BZOJ3879]SvT
    [BZOJ1339] [Baltic2008] Mafia / 黑手党
    [BZOJ1834] [ZJOI2010] network 网络扩容
    [BZOJ1449] [JSOI2009]球队收益 / [BZOJ2895] 球队预算
    [BZOJ2597] [WC2007]剪刀石头布
    [BZOJ1283]序列
    [BZOJ2127]happiness
    Java公开课-04.异常
    Java公开课-03.内部类
  • 原文地址:https://www.cnblogs.com/darker-wxl/p/12579014.html
Copyright © 2011-2022 走看看