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.
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].
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.
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
3
4 3 1
题目大意:给出每个人喜欢的活动,有相同活动的处于一个社交网络,问有多少个社交网络,并从高到低给出每个社交网络人数。
思路:建立一个hobby的数组,当该hobby[x]第一次出现,则hobby[x] = i,i为对应的人的序号,按照题目所给数据:hobby[2] = 1 ,hobby[7]=1, hobby[10] = 1 ,hobby[4] = 2 ,hobby[5] = 3 此时下一个是hobby[4] != 0,所以此时用union函数合并,变成了father[4 ] =2……依次这样做下去,最后得到2的孩子节点有4、6、8,3的孩子节点有5、7;1是独立的,所以有三个社交网络,依次是4、3、1.
#include
#include "algorithm"
using namespace std;
const int maxx = 1100;
int n,temp,index,ans=0;
int isroot[maxx],father[maxx],hobby[maxx]; //第一个表示该节点是否是根节点,第二个存放父亲节点,第三个记录喜欢活动的人。
void init(int x){
for (int i = 1; i <= x; ++i) {
father[i]=i;
isroot[i] = 0;
}
}
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;
}
bool cmp(int x,int y){
return x>y;
}
void Union(int x,int y){
int fax = findfather(x);
int fay = findfather(y);
if (fax != fay){
father[fax] = fay;
}
}
int main() {
cin>>n;
init(n);
for (int i = 1; i <= n; ++i) {
scanf("%d:",&temp);
for (int j = 0; j < temp; ++j) {
scanf("%d",&index);
if (hobby[index] == 0){
hobby[index] = i;
}
Union(i, findfather(hobby[index]));
}
}
for (int i = 1; i <= n; ++i) {
isroot[findfather(i)]++;
}
sort(isroot+1,isroot+n+1, cmp);
for (int i = 1; i <= n; ++i) {
if (isroot[i] != 0) ans++;
}
printf("%d\n",ans);
for (int i =1 ; i <= ans; ++i) {
if (i==1) printf("%d",isroot[1]);
else printf(" %d",isroot[i]);
}
}