1107 Social Clusters (考察并查集)

  大致题意就是给出 N个人的兴趣爱好,如果A与B有相同的爱好H1,那么A与B是朋友,如果B与C有相同的爱好H2,那么B与C是朋友,进一步有A与C是朋友。

输入样例分析:

8  //表示有8个人
3: 2 7 10 //表示人物 1有3个爱好,分别是2 7 10
1: 4     //表示人物 2有1个爱好,分别是4 
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4

 整理成格式

爱好:人物,人物,... 

1: 7
2: 1
3: 3 5
4: 2 4 6 8
5: 3 7
6: 7
7: 1
8: 7
10: 1

 我们可以发现 

爱好3包含人物3、人物5,爱好5包含人物3、人物7,所以3 5 7是一个朋友圈。

爱好4包含人物2、人物4、人物6、人物8,所以2 4 6 8是一个朋友圈。

最后, 1 是一个朋友圈。

所以一共有三个朋友圈。

 1 #include<iostream>
 2 #include<vector>
 3 #include<map>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 2000;
 7 map<int,vector<int> > mp;
 8 int father[maxn];
 9 int isRoot[maxn] = {0};
10 //第一步,初始化所有集合
11 void init(int n) {
12     for(int i = 1; i <= n; ++i)
13         father[i] = i;
14 }
15 //第二步,查找根结点
16 int findFather(int a) {
17     int b = a;
18     while(a != father[a])//找到根结点
19         a = father[a];
20     while(b != father[b]) {//查找根结点时,路径上的所有结点指向根结点
21         int t = b;
22         b = father[b];
23         father[t] = a;
24     }
25     return a;
26 }
27 
28 //第三步,合并a,b所在的集合
29 void Union(int a,int b) {
30     int fa = findFather(a);
31     int fb = findFather(b);
32     if(fa != fb)
33         father[fa] = fb;
34 }
35 bool cmp(int a,int b) {
36     return a > b;
37 }
38 int main() {
39     int n;
40     scanf("%d",&n);
41     for(int i = 1; i <= n; ++i) {
42         int k,h;
43         scanf("%d:",&k);
44         for(int j = 0; j < k; ++j) {
45             scanf("%d",&h);
46             mp[h].push_back(i);
47         }
48     }
49     init(n);
50     for(auto it = mp.begin(); it != mp.end(); ++it) {
51         if(it->second.size() > 1) {
52             for(int i = 1 ; i < it->second.size(); ++i) {
53                 Union(it->second[0],it->second[i]);
54             }
55         }
56     }
57     int cnt = 0;
58     for(int i = 1; i <= n ; ++i) {
59         int f = findFather(i);
60         if(isRoot[f] == 0) cnt++;
61         isRoot[f]++;
62     }
63     printf("%d\n",cnt);
64     sort(isRoot+1,isRoot+1+n,cmp);
65     for(int i = 1; i <= cnt; ++i) {
66         if( i > 1) printf(" ");
67         printf("%d",isRoot[i]);
68     }
69     return 0;
70 }

 

posted @ 2020-03-04 19:57  tangq123  阅读(191)  评论(0编辑  收藏  举报