How Many Tables(并查集)

用并查集求连通块

进行了路径压缩,用t数组来标记联通块的个数(find函数是用来查找是否连通的)

记得一定要经pre[]数组初始化。

代码:

#include <iostream>
#include <string.h>
using namespace std;
#define MAX 1005
int pre[MAX];
int T;
int N,M;
int  find(int x)
{
    int r=x;
    while(pre[r]!=r)
    {
        r=pre[r];
    }
    int i=x,j;
    while(i!=r)
    {
        j=pre[i]; // 在改变上级之前用临时变量  j 记录下他的值
        pre[i]=r;//把上级改为根节点
        i=j;
    }
    return r;
}
void Union(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
        pre[fy]=fx;
}
int main()
{
    int x,y;
    int t[MAX];
    cin>>T;
    while(T--)
    {
        cin>>N>>M;
        for(int i=1;i<=N;i++)//务必记住并查集先初始化;
            pre[i]=i;
        for(int i=1;i<=M;i++)
            {
                cin>>x>>y;
                Union(x,y);
            }
            memset(t,0,sizeof(t));
        for(int i=1;i<=N;i++)
            t[find(i)]=1;//经所有的联通块标记,之后按照标记统计个数。如果多个数字构成一个联通块,
            int ans=0;
            for(int i=1;i<=N;i++)
                if(t[i])ans++;
                cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/guagua_de_xiaohai/article/details/80739100