并查集 (pdsuw)整理

关于并查集,我们先引一个简单的问题

看完这个问题后我们再聊一聊并查集在其中的思想

 

.亲戚关系问题,给出N个人,对于这N个人,我们给出M起亲戚关系,然后询问任意两个人是否是亲戚,该怎么去判断呢?

 

 

#include<stdio.h>

#include<iostream>

 

using namespace std;

 

int N,M,Q;

int s[1000];

void initSet(){//并查集初始化

    for( int i = 1; i <= N; i++){

        s[i]=i;

    }

}

int findSet(int x){//寻找根节点

    while(x!=s[x])

    {

        x = s[x];

    }

    return x;

}

int unionSet(int x,int y){//合并集合

    if(x!=y){

        s[x] = y;

    }

}

int main(){

    while(~scanf("%d%d",&N,&M)){

        initSet();//初始化

        int a,b,sa,sb;

        while(M--){

            scanf("%d%d",&a,&b);

            sa = findSet(a);

            sb = findSet(b);

            unionSet(sa,sb);

        }/*这里把给出数据的根找出,然后将根合并,当集合里只有一个元素时只是将两个元素并入一个集合,换句话说,如果把单独的元素也看出集合的话,就是将两个集合建立关系*/

        scanf("%d",&Q);

        while(Q--){

            scanf("%d%d",&a,&b);

            sa = findSet(a);//找根

            sb = findSet(b);

            if(sa == sb)//将两个根进行比较

                printf("属于同一集合/n");

            else

                printf("不属于同一集合/n");

        }

    }

 

}

 

 

我们模拟一下它的过程

A   1 2 3 4 5 6 7 8 9

S[a ] 1 2 3 4 5 6 7 8 9

这是一个初始化的集合,每个元素都单独存在;

 

我们把 3 4 并在一起

Find 3的根 为 3;

Find 4 的根为 4;

他们通过union函数合并之后,就如下;

A   1 2 3 4 5 6 7 8 9

S[a ] 1 2 3 3 5 6 7 8 9

 

将4 5 并在一起

A   1 2 3 4 5 6 7 8 9

S[a ] 1 2 3 3 3 6 7 8 9

 

将2 3并在一起

A   1 2 3 4 5 6 7 8 9

S[a ] 1 2 2 3 3 6 7 8 9

 

好,我们来findset,我们会发现,2,3,4,5findset找到的根都是2,同时也将他们并成了一个集合

这比较直观的体现了并查集合并的过程

希望对各位新coder有帮助,谢谢。

猜你喜欢

转载自blog.csdn.net/masterwu1/article/details/82430850
今日推荐