好朋友(考察并查集)
题目:
如果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: