并查集模板poj2524

版权声明:转载注明出处!!! https://blog.csdn.net/xhpaqh/article/details/81488829

并查集可以确定连通分量,各边与各边的关系。与克鲁斯科尔最小生成树算法类似。具体模板如下,,,

//初始化函数
void Init(int n)
{
    int i;
    for(i=1;i<=n;i++)
        father[i]=i;
}
//查找函数
int Find(int x)
{
    return x == father[x] ? x : father[x] = find(father[x]);
}
//合并函数
void combine(int a,int b)
{
    int temp_a,temp_b;
    temp_a=Find(a);
    temp_b=Find(b);

    if(temp_a!=temp_b)
        father[temp_a]=temp_b;
}
//确定连通分量个数
int find_ans(int n)
{
    int i,sum=0;
    for(i=1;i<=n;++i)
        if(father[i]==i)
            ++sum;
    return sum;
}

以poj2524为例

#include<stdio.h>
const int maxn=50010;
int father[maxn];
int n,m,x,y;
void lnit(int n){
    for(int i=1;i<=n;i++){
        father[i]=i;
    }
}
int find(int x){
    return x == father[x] ? x : father[x] = find(father[x]);
}
void combine(int a,int b){
    int temp_a,temp_b;
    temp_a=find(a);
    temp_b=find(b);
    if(temp_a!=temp_b){
        father[temp_a]=temp_b;
    }
}
int main(){
    int num=0;
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0)break;
        num++;
        lnit(n);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            combine(x,y);
        }
        int sum=0;
        for(int i=1;i<=n;i++){
            if(find(i)==i){
                sum++;
            }
        }
        printf("Case %d: %d\n",num,sum);
    }
} 

还有poj1611可以练习练习

猜你喜欢

转载自blog.csdn.net/xhpaqh/article/details/81488829