数据结构:并查集

给定n个元素,我们要把属于同类的元素归并,并且要查找这个元素属于哪一类

并查集常常用来处理不相交集合的合并和查询问题

我们先给出并查集需要记住的唯一一个东西,带路径压缩的找爹函数

int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}

然后给出一个归并操作,很容易看明白

            int a,b;
            cin>>a>>b;
            int f1=find(a);
            int f2=find(b);
            if(f1!=f2)
            {
                f[f2]=f1;
                ans--;
            }

如果爹不一样就让这两棵树的所有儿子全连在一个祖先上,可持久化时并不支持此操作

另外,刚开始的初始化操作也十分容易

        for(i=1;i<=n;i++)
            f[i]=i;

那就是每个元素先自成一家

完整的实现是一道题的代码,他问你一个学校的宗教种类上限,给你的若干个数据是某两个学生是否属于同一宗教

因为我们统计的是种类,所以在这里每找到一个不一样的宗教就归并,这样就能避免重复统计

完整的实现如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int f[50005],ans;
 5 int n,m,p=1,i;
 6 int find(int x)
 7 {
 8     return x==f[x]?x:f[x]=find(f[x]);
 9 }
10 int main()
11 {
12     while(cin>>n>>m)
13     {
14         if(n==0&&m==0)break;
15         for(i=1;i<=n;i++)
16             f[i]=i;
17         ans=n;
18         for(i=1;i<=m;i++)
19         {
20             int a,b;
21             cin>>a>>b;
22             int f1=find(a);
23             int f2=find(b);
24             if(f1!=f2)
25             {
26                 f[f2]=f1;
27                 ans--;
28             }
29         }
30         printf("Case %d: %d\n",p++,ans);
31     }
32     return 0;
33 }

 

posted @ 2018-07-13 13:37  静听风吟。  阅读(186)  评论(0编辑  收藏  举报