您的位置:首页 > 其它

并查集 模板

2015-04-16 08:46 337 查看
知识点

并查集是一种树型的数据结构,用于处理一些不相交集合的合并问题。

并查集的主要操作有

1-合并两个不相交集合

2-判断两个元素是否属于同一个集合

3-路径压缩

 

我转载的一个并查集介绍:(很详细)http://blog.csdn.net/xiaotaoqibao/archive/2009/08/14/4447995.aspx

 

 

[c-sharp] view
plaincopy

#include <iostream>  

using namespace std;  

#define N 100005  

  

struct set  

{  

    int parent;  //记录父节点  

    int rank;    //记录集合的节点数  

}elem
;  

  

int MAX;  

  

void init()  

{  

    int i;  

    for(i=0;i<=N;i++)  

    {  

        elem[i].parent=i;  

        elem[i].rank=1;  

    }  

}  

  

int Find(int x)  

{  

    int root,temp;  

    temp=x;  

    while(x!=elem[x].parent)    //寻找根节点  

        x=elem[x].parent;  

    root=x;  

    x=temp;  

    while (x!=elem[x].parent)   //压缩路径,全部赋值为根节点的值  

    {  

        temp=elem[x].parent;  

        elem[x].parent=root;  

        x=temp;  

    }  

    return root;  

}  

  

void Union(int a,int b)   //合并两个集合  

{  

    int x,y;  

    x=Find(a);  

    y=Find(b);  

    if(elem[x].rank>=elem[y].rank)  

    {  

        elem[y].parent=elem[x].parent;  

        elem[x].rank+=elem[y].rank;  

        if(MAX<elem[x].rank)  

            MAX=elem[x].rank;  

    }  

    else  

    {  

        elem[x].parent=elem[y].parent;  

        elem[y].rank+=elem[x].rank;  

        if(MAX<elem[y].rank)  

            MAX=elem[y].rank;  

    }  

}  

  

int main()  

{  

    int n;  //有关系的对数  

    int a,b,x,y;  

    while (scanf("%d",&n)!=EOF)  

    {  

        init();  

        MAX=-1;  

        while (n--)  

        {  

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

            x=Find(a);  

            y=Find(b);  

            if(x!=y)      

                Union(a,b);//a和b不是一个集合的,合并这两个集合  

        }  

        if(MAX!=-1)  

            printf("%d/n",MAX);   //输出最大集合的节点数  

        else  

            printf("1/n");   //此时n=0,证明都是没关系的人  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: