L3-003. 社交集群(并查集)
L3-003. 社交集群
在社交网络平台注册时,用户通常会输入自己的兴趣爱好,以便找到和自己兴趣相投的朋友。有部分兴趣相同的人们就形成了“社交集群”。现请你编写程序,找出所有的集群。
输入格式:
输入的第一行给出正整数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 上述例子
4(第2.4.6.8人)
3(第2,5,7人)
1(第1人)
社交集群人数总和=总人数n
从3(第2,5,7人)可以看出第二人喜欢5,3 第五人喜欢3 第七人喜欢6 8 1 5,三人能连接起来,就是同一集合 这符合并查集的特点 用并查集解决。 分析:并查集。先写好init、findFather、Union。
0. 每个社交圈的结点号是人的编号,而不是课程。课程是用来判断是否处在一个社交圈的。
1. course[t]表示任意一个喜欢t活动的人的编号。如果当前的课程t,之前并没有人喜欢过,那么就course[t] = i,i为它自己的编号,表示i为喜欢course[t]的一个人的编号
2. course[t]是喜欢t活动的人的编号,那么findFather(course[t])就是喜欢这个活动的人所处的社交圈子的根结点,合并根结点和当前人的编号的结点i。即Union(i, findFather(course[t])),把它们处在同一个社交圈子里面
3. isRoot[i]表示编号i的人是不是它自己社交圈子的根结点,如果等于0表示不是根结点,如果不等于0,每次标记isRoot[findFather(i)]++,那么isRoot保存的就是如果当前是根结点,那么这个社交圈里面的总人数
4. isRoot中不为0的编号的个数cnt就是社交圈圈子的个数
5. 把isRoot从大到小排列,输出前cnt个,就是社交圈人数的从大到小的输出顺序 我们集合元素是人,curse[i]的值指人,下标指兴趣 我们以兴趣为前提,对人进行操作
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> father, isRoot;
int cmp1(int a, int b){
return a > b;
}
///找到x的根节点,路径压缩
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() {
int n, k, t, cnt = ;
int course[] = {};
scanf("%d", &n);
father.resize(n + );
isRoot.resize(n + );
for(int i = ; i <= n; i++)///起初,根节点都是自己
father[i] = i;
for(int i = ; i <= n; i++) {
scanf("%d:", &k);
for(int j = ; j < k; j++) {
scanf("%d", &t);
if(course[t] == )
course[t] = i;
Union(i, findFather(course[t]));///将第i个人与有兴趣t的人所在的社交集群合并
}
}
///计算集合元素个数
for(int i = ; i <= n; i++)
isRoot[findFather(i)]++;
///集合个数
for(int i = ; i <= n; i++) {
if(isRoot[i] != )
cnt++;
}
printf("%d\n", cnt);
sort(isRoot.begin(), isRoot.end(), cmp1);
for(int i = ; i < cnt; i++) {
printf("%d", isRoot[i]);
if(i != cnt - ) printf(" ");
}
return ;
}
#include "cstdio"
#include "vector"
#include "algorithm"
using namespace std;
vector<int>father,isRoot;
bool cmp(const int a,const int b){
return a>b;
}
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 fa=findFather(a);
int fb=findFather(b);
if(fa!=fb)
father[fa]=fb;
}
int main()
{
int n,course[]={},k,t;
while(~scanf("%d",&n)&&n){
father.clear();
isRoot.clear();
father.resize(n+);
isRoot.resize(n+);
for(int i=;i<=n;i++)
father[i]=i;
for(int i=;i<=n;i++){
scanf("%d:",&k);
for(int j=;j<k;j++){
scanf("%d",&t);
if(course[t]==)
course[t]=i;
Union(i,findFather(course[t]));
}
}
for(int i=;i<=n;i++){
isRoot[findFather(i)]++;
}
int cnt=;
for(int i=;i<=n;i++)
{
if(isRoot[i]!=)
cnt++;
}
printf("%d\n",cnt);
sort(isRoot.begin(),isRoot.end(),cmp);
for(int i=;i<cnt;i++){
printf("%d",isRoot[i]);
if(i!=cnt-)
printf(" ");
}
printf("\n");
}
return ;
}
L3-003. 社交集群(并查集)的更多相关文章
- 天梯L3-003. 社交集群——并查集
在社交网络平台注册时,用户通常会输入自己的兴趣爱好,以便找到和自己兴趣相投的朋友.有部分兴趣相同的人们就形成了“社交集群”.现请你编写程序,找出所有的集群. 输入格式: 输入的第一行给出正整数N(&l ...
- MongoDB之分片集群与复制集
分片集群 1.1.概念 分片集群是将数据存储在多台机器上的操作,主要由查询路由mongos.分片.配置服务器组成. ●查询路由根据配置服务器上的元数据将请求分发到相应的分片上,本身不存储集群的元数据, ...
- 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...
- Redis集群(五):集群搭建
一.本文目的 演示在一台机器上搭建3主3从的redis集群,通过演示了解redis集群的搭建,使用和注意事项 二.搭建说明 1.同一台机器搭建3主3从的伪集群 ...
- rabbitMQ集群部署以及集群之间同步
MQ集群部署 期待的部署架构 其中,一个机房有两台机器部署MQ,并组成集群,有一个机房的MQ集群作为中心集群,其他机房的MQ集群将消息同步到中心MQ集群中. 安装erlang,略.. 安装rabbit ...
- 搭建mongodb集群(副本集+分片)
搭建mongodb集群(副本集+分片) 转载自:http://blog.csdn.net/bluejoe2000/article/details/41323051 完整的搭建mongodb集群(副本集 ...
- 分布式缓存技术redis学习(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...
- Tomcat集群,Nginx集群,Tomcat+Nginx 负载均衡配置,Tomcat+Nginx集群
Tomcat集群,Nginx集群,Tomcat+Nginx 负载均衡配置,Tomcat+Nginx集群 >>>>>>>>>>>> ...
- 基于Hadoop集群的HBase集群的配置
一 Hadoop集群部署 hadoop配置 二 Zookeeper集群部署 zookeeper配置 三 Hbase集群部署 1.配置hbase-env.sh HBASE_MANAGES_ZK:用来 ...
- Couchbase集群和Redis集群解析
Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...
随机推荐
- Word中使用宏调整表格
Dim i As Integer For i = 1 To Selection.Tables.Count Selection.Tables(i).Columns(9).Delete Selecti ...
- [转]Visual Studio 项目类型 GUID 清单
转自:https://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs Complete li ...
- 用travis-ci编译android版nodejs
第一步: fork 第二步: 添加.travis.yml 在repository根目录添加.travis.yml文件,在其中添加以下内容. language: c before_install: - ...
- 使用JDK自带的keytool工具生成证书
一.keytool 简介 keytool 是java用于管理密钥和证书的工具,它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及 ...
- 在 Ubuntu 16.04 LTS 上安装 Python 3.6.0
原文连接:https://segmentfault.com/a/1190000007912666 最近 Python 3 发布了新版本 Python 3.6.0,好像又加入了不少黑魔法!- 由于暂时不 ...
- POJ 2229 递推
Farmer John commanded his cows to search for different sets of numbers that sum to a given number. T ...
- angular2采用自定义指令(Directive)方式加载jquery插件
由于angular2兴起不久,相关插件还是很少,所以有时候不得不用一些jquery插件来完成项目, 那么如何把jquery插件放到angular2中呢?采用自定义指令! 在上下文之前要引入jquery ...
- 【Linux】Linux修改openfiles后不生效问题?
#次故障问题环境背景: Centos7.4物理机,升级过ssh和ntp: #一般只需要在此文件后面添加4行就行,配置后即可生效(exit再次登录即可生效),此次配置后没生效,reboot还是没生效,在 ...
- php实现base64图片上传方式实例代码
<?php /** * base64图片上传 * @param $base64_img * @return array */ header("content-type:text/htm ...
- 并发(三) CountDownLatch
CountDownLatch 和CyclicBarrier的区别是,CyclicBarrier可以循环使用,CountDownLatch不可以:CyclicBarrier可以有一个Runnable参数 ...