CSU 2125
作者:互联网
https://blog.csdn.net/qq_36258516/article/details/80500815
Description
小Z高中的时候特别喜欢生物,在一次做实验的过程中,小Z配置了n个培养皿,每个培养皿中有着若干种类的细菌,但由于实验室的培养皿数量有限,老师要求小Z尽可能少地使用培养皿。为此,小Z只得将一些培养皿进行混合,但由于一些生物上的特殊要求,只有含有相同细菌的培养皿才能混合,否则细菌将全部死亡。这时候小Z想请求你——CSU(California State University)最厉害的编程高手,希望你帮忙解答出至少需要多少培养皿。
Input
第一行为T(T ≤10),表示有T组数据。
每一组数据首先是一个正整数n(1 ≤ n ≤ 1000),
接下来n行,每行首先一个数k,表示这一个培养皿中有k(1 ≤ k ≤ 100)种细菌,
接下来k个数,a_1,a_2,…,a_k,(1 ≤ a_i ≤100000)。
每个数代表一种细菌的编号,编号之间通过空格隔开,培养皿中的细菌均不相同。
Output
输出最少需要的培养皿数量,每组数据的答案占一行
Sample Input
2
3
3 1 2 3
3 3 9 7
3 4 5 10
4
1 1
3 1 2 3
1 4
4 8 7 4 5
1
2
3
4
5
6
7
8
9
10
Sample Output
2
2
1
2
题意
给出n个培养皿,每个培养皿里面有k种细菌,如果两个培养皿包含相同的至少一种相同的细菌,那么他们可以合并,最后问至少需要几个培养皿。
解题思路
根据题意,很容易就能想到并查集。每个培养皿都相当于是一个集合,如果含有相同的细菌,就直接把并查集合并。这个题也没必要建图,直接把每个培养皿中的第一个细菌作为父节点即可。最后再遍历每个父节点(父节点的p[x]==x)做并查集,如果查询结果是他本身,就需要一个培养皿,累加即可得出结果。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
set<int> s;
int pa[maxn];
int findSet(int x){
return pa[x]==x? x:pa[x]=findSet(pa[x]);
}
int main(){
//freopen("datain.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
s.clear();
for(int i=0;i<maxn;i++)
pa[i]=i;
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
int x,y,tmp;
for(int j=0;j<k;j++){
scanf("%d",&tmp);
if(j==0){
x=findSet(tmp);
s.insert(tmp);
}
else{
y=findSet(tmp);
pa[y]=x;
}
}
}
int ans=0;
for(set<int>::iterator it=s.begin();it!=s.end();++it){
if(findSet(*it)==(*it)) ans++;
}
printf("%d\n",ans);
}
}
标签:10,2125,int,培养皿,pa,findSet,CSU,细菌 来源: https://blog.csdn.net/hanker99/article/details/88396740