题意:有 n 个朋友,他们可能相互认识,A 认识 B,B 认识 C,则 ABC 相互认识,现在给出他们的认识情况,相互认识的人坐一桌,否则需要分开坐,问至少需要多少桌。
其实就是问并查集的个数,在初始情况下一人一个并查集,共 n 个,每次合并操作会减少一个并查集,所以只要每次合并时计数减一下就行,全部合并完之后就可以输出剩余并查集个数了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5
6 int fa[1005],n;
7
8 void init(){
9 for(int i=1;i<=n;i++)fa[i]=i;
10 }
11
12 int find(int x){
13 int r=x,t;
14 while(r!=fa[r])r=fa[r];
15 while(x!=r){
16 t=fa[x];
17 fa[x]=r;
18 x=t;
19 }
20 return r;
21 }
22
23 int main(){
24 int m,t;
25 while(scanf("%d",&t)!=EOF){
26 for(int q=1;q<=t;q++){
27 cin>>n>>m;
28 int c=n;
29 int i;
30 init();
31 for(i=1;i<=m;i++){
32 int a,b;
33 cin>>a>>b;
34 int x=find(a),y=find(b);
35 if(x!=y){
36 fa[x]=y;
37 c--;
38 }
39 }
40 cout<<c<<endl;
41 }
42 }
43 return 0;
44 }