7.3 并查集搜索

并查集算法

并查集算法是一个利用结点关系,进行分类合组的算法

简介

并查集可以通过一个一维数组来实现
我们把每一个点视作一个"独立的,只有一个结点"的树
之后我们可以通过一些条件,逐渐将这些树合并成一棵大树

合并的过程,其实就是找统一的父节点的过程,我们可以自定两条原则:
1.相异的情况下,把右边的父节点改为左边的父节点。视作二者合并成了一组
2.通过两者最高的父节点来进行比较

另外,既然我们通过层层推进找到了某个点的父节点,那么我们在"统一"之后,也可以顺便的把路上的其它结点修改,这样会方便我们的二次寻找

代码示例

    #include <stdio.h>
    int f[1001] = {0} s,n,m,sum = 0 ;
    
    //最开始的初始化
    void init()
    {
        int i ; 
        for(i=0;i<=n;i++)
            f[i] = i ;//最开始的时候,每个点的最高父节点就是它自己
        return ; 
    }

    //这是找爹的递归函数,不停的寻找直到找到最高父节点为止  
    int getf(int v)
    {
        if(f[v] == v){
            return ; //“集团”内只有一个人的情况
        }
        else
        {
            //路径压缩,每次在函数返回的时候,顺带把路径上的结点都修改
            f[v] = getf(f[v]) ;

            return f[v];
        }
    }

    //合并两个子集的函数、
    void merge(int v , int u)
    {
        int t1,t2 ; //t1,t2指的是两个子集的最高父节点

        t1 = getf(v);
        t2 = getf(u);

        if(t1!=t2){
            //两者不在同一集合中,才进行合并
            f[t2] = t1 ; //向左合并原则
        }
        return ; 
    }

    //主程序
    int main()
    {
        int i,x,y;
        scanf("%d %d",&n,&m);

        init();
        for(i=1;i<=m;i++)
        {
            scanf("%d %d",&x,&y);
            merge(x,y);
        }

        //扫描打印结果
        for(i=1;i<=n;i++)
        {
            if(f[i] == i )
                sum++;
        }
        printf("%d \n",sum);


        getchar();getchar()
        return 0 ;
    }

并查集也被称为“不相交集”数据结构

posted @ 2021-11-19 11:28  RetenQ  阅读(41)  评论(0编辑  收藏  举报