世界上 比金钱个更可贵的是知识,比知识更可贵的是,好奇心。
加油!
并查集 : 合并两个集合 或者查询一个元素是否在集合中
另外还可以 维护一个 数组 记录 结点个数
题目:
思路:
用树,维护集合,链接两个集合或者合并就是把一个根结点的父节点 等于 另一个集合的根结点
AC代码:
#include
using namespace std;
int p[100010];
int find(int x){
if(p[x]!=x) p[x] = find(p[x]);//不是根结点 就把父节点变为根结点
return p[x];
}
int main(){
int a,b,n,m;
scanf("%d%d",&n,&m);
for(int i = 0; i <n;i++) p[i] = i;
string op;
while(m--){
cin>>op;
scanf("%d%d",&a,&b);
if(op[0]=='M'){
p[find(a)] = find(b);
}else{
if(find(a)==find(b)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
3 3
2 3 2
1 2
1 1
输出样例:
1
样例解释:
只需要 给第三头牛 买学习第二种语言的书
解题思路:
并查集!
将每只牛和自己会说的语言连一条边,最后统计联通块的个数 连通块个数减一 即为答案
AC代码:
#include
#include
using namespace std;
int p[40005];
int find(int x){
if(p[x]!=x) p[x] = find(p[x]);
return p[x];
}
int main(){
int n,m;//n头牛 m种语言
scanf("%d%d",&n,&m);
for(int i = 0; i <= n+m;i++) p[i]= i;
for(int i = 0;i<n;i++){
int c,a;
scanf("%d",&c);
while(c--){
scanf("%d",&a);
a += n;
p[find(a)] = find(i);
}
}
int ans = 0;
for(int i = 1;i < n;i++) if(p[i]==i) ans++;
printf("%d",ans-1);
return 0;
}
要注意一个问题 就是 如何区分 牛和语言
n以上的就是 语言
哈哈哈哈哈哈
(未完)
[并查集题目汇总:
https://www.cnblogs.com/zqzxwdm/p/5497654.html