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: 4Sample Output:
3 4 3 1
思路分析:考查并查集。注意搞清逻辑即可
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAX 1000 + 10
using namespace std;
vector<int> vec[MAX];
int father[MAX];
int isRoot[MAX];
int cmp( int a, int b ) {
return a > b ? 1 : 0;
}
void init() {
for( int i = 0; i < MAX; i++ ) {
father[i] = i;
}
}
int findFather( int x ) {
int a = x;
while( x != father[x] ) {
x = father[x];
}
// 路径压缩
while( a != father[a] ) {
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
void Union( int a, int b ) {
int faA = findFather( a );
int faB = findFather( b );
if( faA != faB ) {
father[faA] = faB;
}
}
int main() {
init();
//freopen( "123.txt", "r", stdin );
int n;
scanf( "%d", &n );
int k, hobby;
for( int i = 1; i <= n; i++ ) {
scanf( "%d: ", &k );
for( int j = 0; j < k; j++ ) {
scanf( "%d", &hobby );
vec[i].push_back( hobby );
}
for( int j = 1; j < i; j++ ) {
for( int z = 0; z < vec[i].size(); z++ ) {
if( find( vec[j].begin(), vec[j].end(), vec[i][z] ) != vec[j].end() ) {
Union( j, i );
//printf( "%d %d\n", j, i );
break;
}
}
}
}
int cnt = 0;
for( int i = 1; i <= n; i++ ) {
isRoot[findFather( i )]++;
}
for( int i = 1; i <= n; i++ ) {
if( isRoot[i] ) cnt++;
}
sort( isRoot + 1, isRoot + 1 + n, cmp );
printf( "%d\n", cnt );
for( int i = 1; i <= cnt; i++ ) {
if( i == 1 ) printf( "%d", isRoot[i] );
else printf( " %d", isRoot[i] );
}
return 0;
}