题目分析:

一共有N个编号为1~1000的人,以及一共有编号为1~1000种不同的兴趣,在题目给出1~N编号的人员每个人喜欢的兴趣的id后,要求统计出不同的人员集合的个数以及每个人员几个的人数从大到小输出

注意点:

1.每个输入的人员id范围1~N,但是并不意味着兴趣的id也是1~N,完全有可能是大于N 小于等于1000的其他数

2.通过样例输出我们可以得知,如果有三个人喜欢的是(2,3)(3,5)(5,6)类似这样的三个人是归属一个集合的,换句话说只要某个人和另一个集合中的任何一个人有兴趣的交集,就可以加入这个集合,并不是要求集合中的所有人都要有至少一个的共同兴趣才行

3.在查询的时候避免人员id与兴趣id的混淆

题解:

这里我的方法是用两个vector数组,一个存放id为i的人员喜欢的兴趣的id,另一个存放id为i的兴趣所拥护者的id(我称喜欢i兴趣的人为i兴趣的拥护者),由于最后的答案是输出不同的集合数量以及每个集合的人数,这里我预先规定每个人员集合中有一个领导者,p[i]为id为i的人所属集合的领导者的id,在搜索合并集合之前,每个人都是独立的个体集合,我们的搜索通过dfs实现,出发点是每个人的id,通过查询编号为id的人所喜欢的所有的兴趣,然后进一步查询喜欢这个兴趣的所有人的id,而此时这些人都是和前者有交集的,则p[当前id]就是搜索的起始点的人员的id,然后我们继续查询此时这个人喜欢的兴趣,然后进一步查询这个兴趣所有的拥护者,这些拥护者p[i]也要赋值dfs最初的那个人的id......依次重复(这个过程通过代码的观察更为直观),要注意的是搜索的过程中需要不断将被搜到的新的人员记录下来,每次只深入搜索未搜过的点

当你将所有的人员通过p[i]分成一个一个的集合,每个用户p[i]为所属集合的领导者id后,无论是统计人数还是统计集合数都将迎刃而解

代码:

 1 #include<iostream>
2 #include<stdio.h>
3 #include<vector>
4 #include<set>
5 #include<string.h>
6 #include<cmath>
7 #include<algorithm>
8 using namespace std;
9
10 const int N = 1005;
11 int p[N], n; //p[i]为i属于的集群的首领的id
12 int vis[N]; //i是否已经被分类
13 vector<int> v1[N]; //每个兴趣的拥护者id
14 vector<int> v2[N]; //每个人喜欢的兴趣id
15 int ans[N];
16
17 void dfs(int ori, int now, int type){
18 // printf("ori = %d now = %d type = %d\n", ori, now, type);
19 if(type == 2){
20 for(int i = 0; i < v2[now].size(); i++){
21 dfs(ori, v2[now][i], 1);
22 }
23 }else{
24 for(int i = 0; i < v1[now].size(); i++){
25 int t = v1[now][i];
26 if(vis[t] == 0){
27 vis[t] = 1;
28 p[t] = ori;
29 dfs(ori, t, 2);
30 }
31 }
32 }
33 }
34
35 bool cmp(int x, int y){
36 return x > y;
37 }
38
39 int main(){
40 memset(vis, 0, sizeof(vis));
41 scanf("%d", &n);
42 for(int i = 1; i <= n; i++){
43 int m;
44 scanf("%d:", &m);
45 for(int j = 1; j <= m; j++){
46 int x;
47 scanf("%d", &x);
48 v2[i].push_back(x);
49 v1[x].push_back(i);
50 }
51 }
52 for(int i = 1; i <= n; i++) p[i] = i; //每个人的管理者id 一个集群中所有人以其中一人id为id
53 for(int i = 1; i <= n; i++){
54 if(vis[i] == 0){
55 vis[i] = 1;
56 dfs(i, i, 2); //初始人员id 当前id 第三个变量为1则当前id为兴趣id,查拥护者
57 } // 为2则当前id为拥护者id 查拥护者喜欢的兴趣
58 }
59 int sum = 0;
60 memset(ans, 0, sizeof(ans));
61 for(int i = n; i >= 1; i--){
62 if(p[i] == i){
63 sum++;
64 }
65 ans[p[i]]++;
66 }
67 sort(ans+1, ans+n+1, cmp);
68 printf("%d\n", sum);
69 for(int i = 1; i <= sum; i++){
70 if(i != 1) printf(" ");
71 printf("%d", ans[i]);
72 }
73 printf("\n");
74 return 0;
75 }

PAT天梯赛练习 L3-003 社交集群 (30分) DFS搜索的更多相关文章

  1. PAT 天梯赛 是否同一棵二叉搜索树   (25分)(二叉搜索树 指针)

    给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果 ...

  2. PAT 天梯赛 L3-003. 社交集群 【并查集】

    题目链接 https://www.patest.cn/contests/gplt/L3-003 思路 并查集 用一个 cou[i] 来表示 第 i 门课程 的第一个 感兴趣的人 并的时候 判断 cou ...

  3. PAT天梯赛练习题——L3-003. 社交集群(并查集按秩合并)

    L3-003. 社交集群 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在社交网络平台注册时,用户通常会输入自己的兴趣爱好, ...

  4. 【PTA 天梯赛】L3-003 社交集群(并查集)

    当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友.一个“社交集群”是指部分兴趣爱好相同的人的集合.你需要找出所有的社交集群. 输入格式: 输入在第一行 ...

  5. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  6. L3-003. 社交集群(并查集)

    L3-003. 社交集群 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在社交网络平台注册时,用户通常会输入自己的兴趣爱好, ...

  7. L2-2 社交集群 (25 分)(一个写挫的并查集)

    题目: 思路: 就是一个并查集的裸题,不过在数据查找方面可能不好处理,暴力完全可以解决这个问题啊!! #include <bits/stdc++.h> #include <cstdi ...

  8. PAT天梯赛 L1-049 天梯赛座位分配

    题目链接:点击打开链接 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] ...

  9. PAT天梯赛L3-007 天梯地图

    题目链接:点击打开链接 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至 ...

随机推荐

  1. 【SPOJ QTREE4】Query on a tree IV(树链剖分)

    Description 给出一棵边带权(\(c\))的节点数量为 \(n\) 的树,初始树上所有节点都是白色.有两种操作: C x,改变节点 \(x\) 的颜色,即白变黑,黑变白. A,询问树中最远的 ...

  2. STL——容器(List)List 的概念

    1. List 容器的基本概念 1. list 是一个双向链表容器,可高效的进行插入删除元素,他的原理在于每个元素都有两个指针来记录前后两个元素的地址,像火车车厢一样,list 中各个元素在物理存储单 ...

  3. git-服务器搭建-协议概念

    现在开发过程中,很多的实现某一些功能的工具,都是类似的服务器-客户端结构,即C-S架构,例如消息队列的KAFKA,文件存储的EasticSearch,包括我们日常工作中的数据库,他都是一种C-S架构, ...

  4. Oracle 常用语句1

    -- 我是注释信息 sql语句 -- 创建用户: create user 用户名 identified by 密码; create user jack identified by j123; -- l ...

  5. 网站开发学习Python实现-Django学习-介绍(6.1.1)

    @ 目录 1.MVT 2.ORM 关于作者 1.MVT 主要的目的是为了快速,简便的开发数据库驱动的网站,强调代码的复用,多个组件可以很方便以插件的方式服务于整个框架,采用的是MVT设计模式(差不多的 ...

  6. 面试官问我:Object o = new Object() 占用了多少个字节?

    小小面试一下 前言蜜语 最近马师傅火的不要不要的,虽然没有抢到耗子尾汁的商标注册权,但是必须得蹭一波马师傅的热度,下面就是闪电五连鞭的教学环节,你准备好了吗! 在正式内容开始前先甩两篇关于类加载机制和 ...

  7. JXL封装不能使用static关键字问题

    最近要做一个Excel导出的功能,由于文件不大,涉及到了很多Excel表格样式和公式计算,我采用了JXL的方式导出.由于逻辑大多是金额,所以我在封装JXL的时候写了两个静态final变量,代码如下: ...

  8. Java与C#的代码区别

    Java和C#都是编程的语言,它们是两个不同方向的两种语言 相同点: 他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装,继承,多态) 区别: 1.c#中的命名空间是namespace ...

  9. 给因特尔S2600CO服务器主板安装【SAS控制器】驱动

    给因特尔S2600CO服务器主板安装[SAS控制器]驱动 1:首先打开[设备管理器]找到未识别驱动的[SAS控制器]双击进入 2:在[详细信息]选项卡,选择[兼容Id]属性可以看到PCI\VEN_80 ...

  10. Linq基础知识

    开发人员不需要关心将要访问的是关系数据库还是XML数据,或是远程对象,它都采用同样的访问方式. Linq包含一系列的查询技术,其中Linq到对象是对内存进行操作,LINQ到SQL是对数据库的操作,LI ...