时间限制
1000 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue
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
C++:
递归法:
/*
@Date : 2018-02-23 21:28:59
@Author : 酸饺子 ([email protected])
@Link : https://github.com/SourDumplings
@Version : $Id$
*/
/*
https://www.patest.cn/contests/pat-a-practise/1107
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <array>
using namespace std;
static const int MAXK = 1001;
static const int MAXN = 1001;
static array<vector<int>, MAXK> hobbyData;
static vector<int> clusters;
static int N;
static bool checked[MAXN];
void find_friends(vector<vector<int>> &people, int p)
{
checked[p] = true;
++clusters.back();
for (int h : people[p])
{
for (int f : hobbyData[h])
{
if (!checked[f])
find_friends(people, f);
}
}
return;
}
int main(int argc, char const *argv[])
{
scanf("%d", &N);
vector<vector<int>> people(N);
fill(checked, checked+N, false);
int Ki, h;
for (int i = 0; i != N; ++i)
{
scanf("%d:", &Ki);
for (int j = 0; j != Ki; ++j)
{
scanf("%d", &h);
people[i].push_back(h);
hobbyData[h].push_back(i);
}
}
for (int p = 0; p != N; ++p)
{
if (!checked[p])
{
clusters.push_back(0);
find_friends(people, p);
}
}
sort(clusters.rbegin(), clusters.rend());
printf("%d\n", clusters.size());
int output = 0;
for (auto i : clusters)
{
if (output++) putchar(' ');
printf("%d", i);
}
putchar('\n');
return 0;
}
并查集:
/*
@Date : 2018-09-04 22:11:54
@Author : 酸饺子 ([email protected])
@Link : https://github.com/SourDumplings
@Version : $Id$
*/
/*
https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int N;
const int MAXN = 1005;
int root[MAXN];
vector<int> peopleHobbies[MAXN], hobbyPeople[MAXN];
int get_root(int p)
{
if (root[p] < 0)
return p;
else
return get_root(root[p]);
}
void my_union(int p1, int p2)
{
int r1 = get_root(p1), r2 = get_root(p2);
if (r1 != r2)
{
if (root[r1] <= root[r2])
{
root[r1] += root[r2];
root[r2] = root[p2] = r1;
}
else
{
root[r2] += root[r1];
root[r1] = root[p1] = r2;
}
}
return;
}
int main()
{
scanf("%d", &N);
for (int i = 0; i != N; ++i)
{
root[i] = -1;
int K;
scanf("%d:", &K);
for (int j = 0; j != K; ++j)
{
int h;
scanf("%d", &h);
peopleHobbies[i].push_back(h);
hobbyPeople[h].push_back(i);
}
}
for (int i = 0; i != N; ++i)
{
for (int h : peopleHobbies[i])
{
for (int p : hobbyPeople[h])
{
if (p != i)
my_union(i, p);
}
}
}
vector<int> res;
for (int i = 0; i != N; ++i)
{
if (root[i] < 0)
res.push_back(-root[i]);
}
sort(res.begin(), res.end());
printf("%d\n", res.size());
int output = 0;
for (auto it = res.rbegin(); it != res.rend(); ++it)
{
if (output++)
putchar(' ');
printf("%d", *it);
}
putchar('\n');
return 0;
}