题意:有 n 个朋友,他们可能相互认识,A 认识 B,B 认识 C,则 ABC 相互认识,现在给出他们的认识情况,相互认识的人坐一桌,否则需要分开坐,问至少需要多少桌。

其实就是问并查集的个数,在初始情况下一人一个并查集,共 n 个,每次合并操作会减少一个并查集,所以只要每次合并时计数减一下就行,全部合并完之后就可以输出剩余并查集个数了。

 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 }
View Code