并查集(基础)

并查集, 从这个名字上也可以知道是合并和查找集合的, 它也叫不相交的集的数据结构, 典型的例题有食物链, 来判断有多少个独立的树什么的, 下面一个例题,来简单的解释并查集:一个犯罪团伙一共有n个人, 现在只知道谁跟谁一伙, 来求出一共有多少个团伙, 代码如下:

 1 #include <stdio.h>
 2 //并查集
 3 /*此案例是给定总个数, 从1到n, 然后给定谁和谁是一伙的,
 4 输入一个m来确定一个有多少个一伙的, 求出最后一个有几伙*/
 5 int f[1000], n, m, k, sum = 0;
 6 //初始化
 7 void init()
 8 {
 9     for(int i = 1; i <= n; i++)
10         f[i] = i;
11 }
12 //找到它的父亲
13 int getf(int i)
14 {
15     if(i != f[i])
16     {
17         f[i] = getf(f[i]);//路径压缩
18     }
19     return f[i];
20 }
21 //合并函数,
22 void merge(int i, int j)
23 {
24     int t1 = getf(i);
25     int t2 = getf(j);
26     if(t1 != t2)
27     {
28         f[t2] = t1;
29     }
30 }
31 
32 int main()
33 {
34 //    freopen("1.in", "r", stdin);
35     scanf("%d ", &n);
36     init();
37     int m;
38     scanf("%d ", &m);
39     int x, y;
40     for(int i = 1; i <= m; i++)
41     {
42         scanf("%d %d", &x, &y);
43         merge(x, y);
44     }
45     for(int i = 1; i <= n; i++)
46     {
47         if(f[i] == i)
48             sum++;
49     }
50     printf("%d
", sum);
51     return 0;
52 }

测试数据:

10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4

结果如下:

练习题:http://acm.hdu.edu.cn/showproblem.php?pid=1232

 1 #include<iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 1004;
 6 int father[N];
 7 void init()
 8 {
 9     for (int i = 1; i < N; i++)
10         father[i] = i;
11 }
12 
13 int find(int x)
14 {
15     if (x != father[x])
16         father[x] = find(father[x]);//路径压缩
17     return father[x];
18 }
19 void union_set(int a, int b)//合并
20 {
21     int ta = find(a);
22     int tb = find(b);
23     if (ta < tb)
24         father[tb] = ta;
25     else if (ta > tb)
26         father[ta] = tb;
27 }
28 int main()
29 {
30     int n, m;
31     while (~scanf("%d", &n) && n)
32     {
33         scanf("%d", &m);
34         init();
35         int a, b;
36         for (int i = 0; i < m; i++)
37         {
38             scanf("%d %d", &a, &b);
39             union_set(a, b);
40         }
41         int num = 0;
42         for (int i = 1; i <= n; i++)
43             if (father[i] == i)//找连通分量的个数
44                 num++;
45         printf("%d
", num - 1);
46 
47     }
48     return 0;
49 }
View Code
原文地址:https://www.cnblogs.com/Howe-Young/p/4038546.html