好朋友(考察并查集)

题目:

  如果A和B是朋友,B和C是朋友,那么A和C是朋友。现在给出 N个人(编号 1~N),判断可以形成多少个朋友圈。

输入格式:

第一行给出一个 正整数N (<= 100),和  朋友对数 M;

给出 M行 朋友关系。

输出格式:

输出朋友圈的个数。

输入样例 1:

4 2
1 4
2 3

输出样例 1:

2

输入样例 2:

7 5
1 2
2 3
3 1
1 4
5 6

输出样例 2:

3

 1 #include<iostream>
 2 using namespace std;
 3 const int maxn = 200;
 4 int father[maxn]; //存放父结点
 5 int isRoot[maxn] = {0};//根结点为 1
 6 
 7 //第一步,初始化集合
 8 void init(int n) {
 9     for(int i = 1; i <= n; ++i)
10         father[i] = i;
11 }
12 //第二步,查找父亲结点
13 int findFather(int a) {
14     int b = a;//备份 a
15     while(a != father[a]) //找出当前集合的根结点
16         a = father[a];
17     while(b != father[b]) {//把当前集合的所有结点指向根结点
18         int t = b;//备份 b
19         b = father[b];
20         father[t] = a;
21     }
22     return a;
23 }
24 //第三步,合并a,b所在的集合
25 void Union(int a,int b) {
26     int fa = findFather(a);
27     int fb = findFather(b);
28     if(fa != fb)
29         father[fa] = fb;
30 }
31 
32 int main() {
33     int n,m,a,b; //n个结点,m对朋友
34     cin>>n>>m;
35     init(n);
36     for(int i = 0; i < m; ++i) {
37         cin>>a>>b;
38         Union(a,b);//合并a,b所在的集合
39     }
40     for(int i = 1; i <= n; ++i)//遍历所有结点,查找并标记 根结点为 1
41         isRoot[findFather(i)] = 1;
42     int cnt = 0;
43     for(int i = 1; i <= n; ++i)//统计根结点的个数
44         cnt += isRoot[i];
45     cout<<cnt;
46     return 0;
47 }

运行结果 1:

 运行结果 2:

猜你喜欢

转载自www.cnblogs.com/keep23456/p/12408928.html