并查集初步

 

PS:今天入手了一台1993年产的IBM Model M弹簧轴机械键盘,真好用呀真好用~  ^_^

 

并查集经常借助树形数据结构来实现。

设Father[i]表示元素i所属于的集合编号。初始化Father[x]=x;即每个节点都是单独的一棵树

并查集具有两项基本操作:

  1. Find(i) :返回元素i所属于的集合的编号

Int Find(int x)

{

         If (x!=Father[x])

               Father[x]=Find(Father[x])     //此处用到了路径压缩优化

            Return Father[x];

      }

  1. Union(x,y):合并元素x和元素y所在的集合

Void Union(int x,int y)

{

         Int fx=Find(x);

         Int fy=Find(y);

         If (fx!=fy)

               Father[fy]=fx;

      }

 

 

来看一个简单的例题:

Eg1:亲戚(原题网上一抓一大把T^T)

赤裸裸的并查集,不再解释了~

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 int n,m,p,tx,ty,i,x,y,j;
 5 int f[10000];
 6 
 7 int find(int x)
 8 {
 9     if (f[x]!=x)
10         f[x]=find(f[x]);
11     return f[x];
12 }
13 
14 void iunion(int x,int y)
15 {
16     int fx,fy;
17     fx=find(x);
18     fy=find(y);
19     if (fx!=fy) 
20         f[fx]=fy;
21 }
22 
23 int main()
24 {
25     cin>>n>>m>>p;
26     memset(f,0,sizeof(f));
27     for (i=1;i<=n;i++)
28         f[i]=i;
29         
30     for (i=1;i<=m;i++)
31     {
32         cin>>x>>y;
33         iunion(x,y);
34             for (j=1;j<=n;j++)  cout<<f[j]<<"  ";
35             cout<<endl;
36     }
37         
38     for (i=1;i<=p;i++)
39     {
40         cin>>x>>y;
41         tx=find(x);
42         ty=find(y);
43         if (tx==ty) cout<<"yes"<<endl;
44             else cout<<"no"<<endl;
45     }
46 }
View Code

相关文章: