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是开 ...
随机推荐
- 一步一步学Linq to sql(二):DataContext与实体
DataContext DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入 ...
- NB-IOT的键值对
1. 关于NB-IOT的软件开发,有一个功能,NB收到数据的时候可以唤醒处于低功耗下的MCU. 2. 2个键值对可以配置这个功能.使用键值对的方式. 3. 遇到的第一个问题,<config> ...
- PHP通过copy()函数来复制一个文件
PHP通过copy()函数来复制一个文件.用法如下: bool copy(string $source, string $dest) 其中$source是源文件的路径,$dest是目的文件的路径.函数 ...
- Android中StackOverflow的问题
最近出现了一个让人抓狂的问题. 现在的项目中,制作了一个界面非常复杂.Fragment中嵌套下拉刷新的Listview 这样一个布局,在3.0以上的手机上都表现良好问题!但是在2.x的比较弱爆的手机上 ...
- 关于ArrayList add()方法 中的引用问题
ArrayList的add方法每次添加一个对象时,添加 的是一个对象的引用,比如进行循环操作10次 lists.add(a) 每次 a会改变 ,这时候你会发现你在lists里添加了10个相同的对象a ...
- linux学习(二)——汤哥的推荐书籍
成为一名精通 Linux程序设计的高级程序员一直是不少朋友孜孜以求的目标. 根据中华英才网统计数据,北京地区 Linux 程序员月薪平均为 Windows程序员的 1.8 倍.Java 程序员的 2. ...
- json.dumps错误:'utf8' codec can't decode byte解决方案
一次在使用json.dumps()过程中,出现错误提示: ERROR:"UnicodeDecodeError: 'utf8' codec can't decode byte 0xe1 in ...
- [翻译] ASP.NET Core 简介
ASP.NET Core 简介 原文地址:Introduction to ASP.NET Core 译文地址:asp.net core 简介 翻译:ganqiyin ...
- nopcommerce商城系统--技术与系统需求
原址:http://www.nopcommerce.com/technologysystemrequirements.aspx 在这里,我们将着眼于nopCommerce的系统要求.为了运行nopCo ...
- 远程sql数据库连接不上,provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接 错误解决
错误信息: “ 标题: 连接到服务器------------------------------ 无法连接到 192.168.1.20. ------------------------------其 ...