并查集专题练习:好朋友(未完待续)

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集专题练习:好朋友(未完待续)相关的知识,希望对你有一定的参考价值。

有空再把题目补上

输入样例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. 这题放在并查集的专题后面,有查找也有合并,需要具备的基础只是是合并和查找的函数要会写(都很简单)。但是读到每组好朋友的关系时,应该是调用合并函数,而不是随便把一个设置为另一个的父亲orz。

2. 在读朋友关系前把所有节点的父节点都设置成自身,也就是默认为根节点,大不了之后不是再被覆盖掉。

3. 怎样统计根节点的个数呢?起初的设想是,用一个向量容器存放,对于每一个结点,先看它的源头在不在容器内,不再才加进去,最后输出向量的大小。优化方案:不用向量容器,直接用集合容器,不用判断在不在,插入所有的源节点,最后输出集合大小即可。

4. 注意合并集合的函数,是让一个根结点成为另一个的子节点,而不是参数a成为参数b的子节点。

AC代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
typedef long long LL;

using namespace std;

const int maxn = 100;

int F[maxn];

int findSource(int x){
	while(x!=F[x]){
		x = F[x];
	}
	return x;
}

void unite(int a,int b){//将a和b所在的集合合并 
	int sa = findSource(a);
	int sb = findSource(b);
	if(sa!=sb){
		F[sa] = sb;//这里特别容易写错
	}
}

int main(){
	
	int n,m,a,b;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		F[i] = i;
	}
	for(int i=0;i<m;i++){
		scanf("%d %d",&a,&b);
		unite(a,b);
	}
	set<int> roots;
	for(int i=1;i<n;i++){
		int source = findSource(i);
		roots.insert(source);
	}
	
	printf("%d",roots.size());
	
	return 0;
}

以上是关于并查集专题练习:好朋友(未完待续)的主要内容,如果未能解决你的问题,请参考以下文章

java员工管理系统练习(未完待续)

并查集并查集专题总结

团体程序设计天梯赛-练习集 L3-003 社交集群 并查集 解题报告

Python语言基础与应用 (P23)上机练习:容器类型操作(未完待续)

[专题四] 并查集

python核心编程第二版 第二章练习题解答 未完待续