zoukankan      html  css  js  c++  java
  • 并查集

    并查集

    介绍:

    并查集是一种高效处理集合的数据结构,可以执行元素所在集合的查找,集合的合并等等,是一种非常高效的算法,常常与其他算法结合来高效的解决问题。

    基本操作:

    1. 合并(Union):合并两个集合。
    2. 查询(find):查询元素所在集合。

    具体实现:

    并查集是一种树形结构,在实际操作中我们将每一个集合用一颗树来代表,而树的标志就是根节点。用一组数据举例:

    1,2,3,4,5,6,7,8;最开始他们自己各自为一个集合,对于两个基本操作,先说查找,我们将树根作为标记节点,所以对于每个数据我们都去查找他的根节点即可,所以他的find操作为:

    int find(int x){
        int now=x;
        while(now!=father[now]){
            now=father[now];
        }
        return now;
    }
    

    对于合并操作,因为一个集合的代表为树的根节点,所以当合并两个集合时,我们先进行判断两个元素所在集合是否为一个,不为一个集合的话,我们只需要将其中一个集合的根接到另一个集合的根上即可将这两个集合合并:

    void uniongroup(int x,int y){
        int boot1=find(x);
        int boot2=find(y);
        if(boot1!=boot2){
            father[boot1]=boot2;
        }
        return;
    }
    

    对于以上两部分代码,存在一个严重的效率问题,观察之后我们会发现,如果经过一些操作后。一棵树变成了一条长长的单链,那么查询操作将会变得十分的缓慢,同时由于合并操作也会用到查询才做,所以算法效率是十分不够的,所以引入路径压缩的做法。

    路径压缩:

    对于一颗树,在并查集里我们并不关心路径如何,我们只关心这颗树有哪些节点,以及这颗树的根节点是谁,所以我们可以将非根节点间的路径全部取消,将每一个非根节点都连接到根节点上,这样我们每次的查询几乎都是O(1),这回大大提高效率,具体做法就是,我们每查询一个节点的所在树根节点,我们都在查询过程中不断更改节点的位置,为了便于修改,我们采用递归的方式。

    int Find(int x){
        if(x==father[x])
            return x;
        return father[x]=Find(father[x]);
    }
    

    这样Find每次返回的都是根节点,所以我们同时更新了x点的父节点为根节点,这就相当于把节点直接连到了根节点上,这样下次的查询就变得相当快捷了。同理只需要将uniongroup中的find函数替换为Find操作即可。

    void uniongroup(int x,int y){
        int boot1=Find(x);
        int boot2=Find(y);
        if(boot1!=boot2){
            father[boot1]=boot2;
        }
        return;
    }
    

    例题:

    题目描述

    若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

    输入格式

    第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。

    以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Mi和Mj具有亲戚关系。

    接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。

    输出格式

    P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。

    样例

    输入

    6 5 3
    1 2
    1 5
    3 4
    5 2
    1 3
    1 4
    2 3
    5 6
    

    输出

    Yes
    Yes
    No
    
    /******************************************
    /@Author: LeafBelief
    /@Date: 2020-03-07
    /@Remark:    
    /@FileName: bingchaji
    ******************************************/
    #include <bits/stdc++.h>
    #define CSE(x, y) memset(x, y, sizeof(x))
    #define lowbit(x) (x & (-x))
    #define INF 0x3f3f3f3f
    #define FAST                     
        ios::sync_with_stdio(false); 
        cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    
    const int maxn = 11111;
    int father[maxn];
    
    int Find(int x)
    {
        if (x == father[x])
            return x;
        return father[x] = Find(father[x]);
    }
    
    void uniongroup(int x, int y)
    {
        int boot1 = Find(x);
        int boot2 = Find(y);
        if (boot1 != boot2)
        {
            father[boot1] = boot2;
        }
        return;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.in", "r", stdin);
    #endif
        FAST;
        int n, m, p;
        cin >> n >> m >> p;
        for (int i = 1; i <= n; i++)
            father[i] = i;
        for (int i = 0; i < m; i++)
        {
            int x, y;
            cin >> x >> y;
            uniongroup(x, y);
        }
        for (int i = 0; i < p; i++)
        {
            int x, y;
            cin >> x >> y;
            if (Find(x) == Find(y))
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    C#基础视频教程5.3 如何编写简单的超级热键
    spring boot中注入jpa时报could not autowire.No beans of 'PersonRepository' type found
    SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别
    idea如何搭建springboot框架
    Fiddler建好代理后,能连到手机,但手机不能上网了是什么原因
    如何用Fiddler对Android应用进行抓包
    【fiddler】抓取https数据失败,全部显示“Tunnel to......443”
    将excel的数据导入到数据库后都乱码了是怎么回事
    java保存繁体字到数据库时就报错Incorrect string value: 'xF0xA6x8Dx8BxE5xA4...' for column 'name' at row 1
    将爬取的网页数据保存到数据库时报错不能提交JPA,Caused by: java.sql.SQLException: Incorrect string value: 'xF0x9Fx98xB6 xE2...' for column 'content' at row 1
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12435180.html
Copyright © 2011-2022 走看看