HDU 1213 How Many Tables 并查集

题目描述:Ignatius,这个人过生日,然后请了很多朋友来聚会,然后并不是他的所有的朋友都互相认识,现在给出他的朋友们相互认识的情况,并且规定,如果1认识2,2认识3,则1认识3,要求每一伙认识的朋友坐在一张桌子上,然后要求一共需要多少张桌子。

解题报告:此题我用的是并查集,也就是将每次输入的一对关系都放到一个集合里面,然后最后将所有的认识的关系压缩到一个节点下,同通俗的说就是把一伙互相认识的人都归到其中一个人的名下,然后统计有多少伙人就可以了。中间有一个压缩路径的操作,不好讲,看代码就知道了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 const int MAX = 1000+5;
 5 
 6 int T,a,b,N,M,prim[MAX];
 7 int find(int k) {
 8     return prim[k]==k? k:(prim[k] = find(prim[k]));
 9 }
10 
11 
12 int main() {
13     scanf("%d",&T);
14     while(T--) {
15         scanf("%d%d",&N,&M);
16         for(int i = 1;i<=N;++i)
17         prim[i] = i;
18         for(int i = 0;i<M;++i) {
19             scanf("%d%d",&a,&b);
20             if(a>b)
21             std::swap(a,b);
22             prim[find(a)] = find(b);
23         }
24         for(int i = 1;i<=N;++i)  //这一步压缩路径,必要 ,
25         //将所有在一个集合内的元素压缩成所有前去节点相同 
26         find(i);
27         std::sort(prim+1,prim+N+1);
28         int tot = 0;
29         int c = -1;
30         for(int i = 1;i<=N;++i)
31         if(prim[i]!=c) {
32             c = prim[i];
33             tot++;
34         }
35         printf("%d
",tot);
36     }
37     return 0;
38 }
View Code
原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3226431.html