时间限制
1000 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
在社交网络平台注册时,用户通常会输入自己的兴趣爱好,以便找到和自己兴趣相投的朋友。有部分兴趣相同的人们就形成了“社交集群”。现请你编写程序,找出所有的集群。
输入格式:
输入的第一行给出正整数N(<=1000),即社交网络中的用户总数(则用户从1到N编号)。随后N行,每行按下列格式列出每个人的兴趣爱好:
Ki: hi[1] hi[2] ... hi[Ki]
其中Ki(>0)是第i个人的兴趣的数量,hi[j]是第i个人的第j项兴趣的编号,编号范围为[1, 1000]内的整数。
输出格式:
首先在第一行输出整个网络中集群的数量,然后在第二行按非递增的顺序输出每个集群中用户的数量。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例: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
#include <iostream>
#include <set>
#include <stdio.h>
#include <string.h>
#include <set>
#include <algorithm>
using namespace std;
set<int> s;
int map[1000];
int intr[1010][1010];
int intrn[1010];
int pi[1010][1010];
int pin[1010];
int pre[1010];
int imax;
int find(int x)//查找根节点
{
int r=x;
while ( pre[r ] != r )//返回根节点 r
r=pre[r ];
int i=x , j ;
while( i != r )//路径压缩
{
j = pre[ i ]; // 在改变上级之前用临时变量 j 记录下他的值
pre[ i ]= r ; //把上级改为根节点
i=j;
}
return r ;
}
void link(int x,int y)//x y连通,
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fx ]=fy;
}
void linkint(int l1,int l2)
{
for(int i = 1;i < intrn[l1];i++)
{
link(intr[l1][0],intr[l1][i]);
// printf(" link %d %d\n",intr[l1][0],intr[l1][i]);
}
for(int i = 0;i < intrn[l2];i++)
{
link(intr[l1][0],intr[l2][i]);
// printf(" link %d %d\n",intr[l1][0],intr[l2][i]);
}
}
int main()
{
s.clear();
memset(intr,0,sizeof(intr));
memset(intrn,0,sizeof(intrn));
memset(map,0,sizeof(map));
int imax = 0;
int t;
scanf("%d",&t);
for(int i = 0;i < t;i++)
{
scanf("%d",&pin[i]);
char USELESS[10];
scanf("%s",USELESS);
for(int j = 0;j < pin[i];j++)
{
int inters;
scanf("%d",&inters);
inters > imax ? imax = inters:imax = imax;
intr[inters][intrn[inters]++] = i;
pi[i][j] = inters;
}
}
for(int i = 0;i <= imax;i++)
{
// printf("%d ->",i);
for(int j = 0;j < intrn[i];j++)
{
// printf("%d ",intr[i][j]);
}
// printf("\n");
}
for(int i = 0;i < t;i++)
{
// printf("人%d -> ",i);
for(int j = 0;j < pin[i];j++)
{
// printf("%d ",pi[i][j]);
}
// printf("\n");
}
for(int i = 0;i < t;i++)
{
pre[i] = i;
}
for(int i = 0;i <= imax;i++)
{
if(intrn[i] > 1)
{
for(int j = 1;j < intrn[i];j++)
{
// printf(" link %d %d\n",intr[i][j],intr[i][j-1]);
link(intr[i][j],intr[i][j-1]);
}
// printf("\n");
}
}
for(int i = 0;i < t;i++)
{
for(int j = 1;j < pin[i];j++)
{
// printf("lineint %d %d\n",pi[i][j - 1],pi[i][j]);
linkint(pi[i][j - 1],pi[i][j]);
}
// printf("\n");
}
for(int i = 0;i < t;i++)
{
// printf("!!!%d %d\n",i,f[i]);
}
for(int i = 0;i < t;i++)
{
map[pre[i]]++;
s.insert(pre[i]);
}
sort(map,map+t);
printf("%d\n",s.size());
for(int i = t-1;i > t-s.size();i--)
{
printf("%d ",map[i]);
}
printf("%d\n",map[t-s.size()]);
}