1107 Social Clusters 30 ☆☆★

github 地址:https://github.com/iofu728/PAT-A-by-iofu728 难度:☆☆★ 关键词:合并 并查集

题目

1107 Social Clusters 30 When register on a social network, you are always asked to specify your hobbies in order to find some potential friends with the same hobbies. A social cluster is a set of people who have some of their hobbies in common. You are supposed to find all the clusters.

Input Specification: Each input file contains one test case. For each test case, the first line contains a positive integer N (≤1000), the total number of people in a social network. Hence the people are numbered from 1 to N. Then N lines follow, each gives the hobby list of a person in the format:

Ki: hi[1] hi[2] ... hi[Ki] where Ki(>0) is the number of hobbies, and hi[j] is the index of the j-th hobby, which is an integer in [1, 1000].

Output Specification: For each case, print in one line the total number of clusters in the network. Then in the second line, print the numbers of people in the clusters in non-increasing order. The numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input: 8 3: 2 7 10 1: 4 2: 5 3 1: 4 1: 3 1: 4 4: 6 8 1 5 1: 4 Sample Output: 3 4 3 1

大意

每个人都有一堆兴趣,只要一堆人中存在两个人之间兴趣有重合,记为一个小团体,计算团体数

思路

  1. 用 v,course 记录当前小团体人员分布,兴趣分布
  2. 每次读取的时候,遍历现有小团体,把重合团体编号存入一个 vector merge
  3. 如果!merge.size(), 则新建一个小团体
  4. 否则合并小团体
  5. 调试的时候发现一个 bug
  • merge.erase 之后存在 merge 中的 id 就不再对应真实 id,需要处理一下

code

/*
 * @Author: gunjianpan
 * @Date:   2018-09-29 19:58:35
 * @Last Modified by:   gunjianpan
 * @Last Modified time: 2018-09-29 21:15:34
 */
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
const int MAXN = 1010;
std::vector<int> pre[MAXN], merges;
std::vector<vector<int> > v, course;
bool vis[MAXN] = {false};

bool sortnum(vector<int> a, vector<int> b) {
  return a.size() == b.size() || a.size() > b.size();
}

int main(int argc, char const *argv[]) {
  int n, num, temp, count = 0;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    scanf("%d:", &num);
    merges.clear();
    fill(vis, vis + MAXN, false);
    count = 0;
    for (int j = 0; j < num; ++j) {
      cin >> temp;
      pre[i].push_back(temp);
      for (int k = 0; k < v.size(); ++k)
        if (!vis[k] && std::find(course[k].begin(), course[k].end(), temp) !=
                           course[k].end()) {
          merges.push_back(k);
          vis[k] = true;
        }
    }
    if (!merges.size()) {
      std::vector<int> top;
      top.push_back(i);
      v.push_back(top);
      course.push_back(pre[i]);
    } else {
      sort(merges.begin(), merges.end());
      int top = merges[0];
      v[top].push_back(i);
      course[top].insert(course[top].end(), pre[i].begin(), pre[i].end());
      for (int j = 1; j < merges.size(); ++j) {
        v[top].insert(v[top].end(), v[merges[j] - count].begin(),
                      v[merges[j] - count].end());
        course[top].insert(course[top].end(), course[merges[j] - count].begin(),
                           course[merges[j] - count].end());
        v.erase(v.begin() + merges[j] - count);
        course.erase(course.begin() + merges[j] - count);
        ++count;
      }
    }
  }
  cout << v.size() << endl;
  sort(v.begin(), v.end(), sortnum);
  for (int i = 0; i < v.size(); ++i) {
    if (i) cout << ' ';
    cout << v[i].size();
  }
  return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
You can use this BibTex to reference this blog if you find it useful and want to quote it.