标签:依次 network namespace mes first view exactly 集合 osi
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:
K?i??: h?i??[1] h?i??[2] ... h?i??[K?i??]
where K?i?? (>0) is the number of hobbies, and h?i??[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
题意:
有N个人,每个人喜欢若干项活动,如果两个人有任意一项活动相同,那么就称他们处于同一个社交网络(若A和B属于同一个社交网络,B和C属于同一个社交网络,那么A、B、C属于同一个社交网络)。
求这N个人总共形成多少个社交网络。
参考代码:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N = 1010; 5 int father[N]; //存放父亲结点 6 int isRoot[N] = {0}; //记录每个结点是否作为某个集合的根结点 7 int course[N] = {0}; 8 int findFather(int x){ //查找x所在集合的根结点 9 int a = x; 10 while(x!=father[x]){ 11 x = father[x]; 12 } 13 //路径压缩 14 while(a != father[a]){ 15 int z = a; 16 a = father[a]; 17 father[z] = x; 18 } 19 return x; 20 } 21 22 void Union(int a,int b){ //合并a和b所在的集合 23 int faA = findFather(a); 24 int faB = findFather(b); 25 if(faA != faB){ 26 father[faA] = faB; 27 } 28 } 29 void init(int n){ //初始化father[i]为i,且flag[i]为false 30 for(int i=1;i<=n;i++){ 31 father[i] = i; 32 isRoot[i] = false; 33 } 34 } 35 36 bool cmp(int a,int b){ //将isRoot数组从大到小排序 37 return a > b; 38 } 39 40 int main(){ 41 int n,k,h; 42 scanf("%d",&n); //人数 43 init(n); 44 for(int i=1;i<=n;i++){ //对每个人 45 scanf("%d:",&k); //活动个数 46 for(int j=0;j<k;j++){ //对每个活动 47 scanf("%d",&h); //输入i号人喜欢的活动h 48 if(course[h] == 0){ //如果活动h第一次有人喜欢 49 course[h] = i; //令i喜欢活动h 50 } 51 Union(i,findFather(course[h])); //合并 52 } 53 } 54 55 for(int i=1;i<=n;i++){ 56 isRoot[findFather(i)]++; //i的跟结点是findFzther(i),人数加1 57 } 58 int ans = 0; //记录集合数目 59 for(int i=1;i<=n;i++){ 60 if(isRoot[i] != 0){ 61 ans++; //只统计isRoot[i]不为0的 62 } 63 } 64 printf("%d\n",ans); //输出集合个数 65 sort(isRoot+1,isRoot+n+1,cmp); 66 for(int i=1;i<=ans;i++){ //依次输出每个集合内的人数 67 printf("%d",isRoot[i]); 68 if(i<ans)printf(" "); 69 } 70 return 0; 71 }
标签:依次 network namespace mes first view exactly 集合 osi
原文地址:https://www.cnblogs.com/mxj961116/p/10586321.html