• 并查集基础(入门)


      最早接触并查集的时候是在做一道最小生成树问题上,当时还不会并查集,题解说用克鲁斯卡尔算法,用并查集来维护,就能够完成最小生成树。

    并查集是什么呢?其实,并查集就是一个集合,它有两种操作,一个是合并(merge),一个是查找(getf)。 合并就是说把具有相同祖先的集合合并成

    为一个集合,查找就是说,查找某些具有相同祖先的集合。当然这个祖先只是我这样叫的(他其实并不是名义上的祖先),很多时候我们会维护很多

    这样的信息,比如说,在求最小生成树的算法中,我们维护的是检查两个顶点是否属于同一个集合,也就是说,判断他们是不是联通,如果联通的话,

    那就肯定不能连接这条边的,因为在一个图中,要想找到一棵树,是不能有环存在的(这个到最小生成树的时候再说).

      然后就是效率问题了,我们知道在查找操作中,肯定会因为n的数目过大而超时,所以我们需要用到路径压缩的知识,防止出现一种奇怪的树,也

    就是全部左偏或者全部右偏而有需要我们对树的叶子节点进行getf()操作。

    先来到有关并查集的最为简单的题目了。

      现在有n个人,分别编号为1,2,3,,,n,然后给出m个关系,比如说:1 2 ,那么1和2就是一个同伙,输出最小的同伙数。

    # include<cstdio>
    # include<iostream>
    
    using namespace std;
    
    # define MAX 12345
    
    int f[MAX];
    int n,m;
    int sum;
    
    void init()
    {
        for ( int i = 1;i <= n;i++ )
        {
            f[i] = i;
        }
    }
    
    int getf( int v )
    {
        if ( f[v]==v )
        {
            return v;
        }
        else
        {
            f[v] = getf(f[v]);
            return f[v];
        }
    }
    
    void merge( int v,int u )
    {
        int t1 = getf(v);
        int t2 = getf(u);
    
        if ( t1!=t2 )
        {
            f[t2] = t1;
        }
    }
    
    int main(void)
    {
        cin>>n>>m;
        init();
        for ( int i = 0;i < m;i++ )
        {
            int t1,t2;
            cin>>t1>>t2;
            merge(t1,t2);
        }
        for ( int i = 1;i <= n;i++ )
        {
            if ( f[i]==i )
            {
                sum++;
            }
        }
        cout<<sum<<endl;
    
        return 0;
    }
    

      有关并查集的东西,以后再更新~

  • 相关阅读:
    Python 必备神器
    python 常用库
    Sublime Text3 配置 Python2 Python3
    Python JSON
    Sublime Text3 3143 注册码
    EFCode First 导航属性
    EF Code First:实体映射,数据迁移,重构(1)
    Entity Framework 复杂类型
    EF 7 Code First
    EF Code First 导航属性 与外键
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4374687.html
Copyright © 2020-2023  润新知