PAT天梯赛练习 L3-003 社交集群 (30分) DFS搜索
题目分析:
一共有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搜索的更多相关文章
- PAT 天梯赛 是否同一棵二叉搜索树 (25分)(二叉搜索树 指针)
给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果 ...
- PAT 天梯赛 L3-003. 社交集群 【并查集】
题目链接 https://www.patest.cn/contests/gplt/L3-003 思路 并查集 用一个 cou[i] 来表示 第 i 门课程 的第一个 感兴趣的人 并的时候 判断 cou ...
- PAT天梯赛练习题——L3-003. 社交集群(并查集按秩合并)
L3-003. 社交集群 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在社交网络平台注册时,用户通常会输入自己的兴趣爱好, ...
- 【PTA 天梯赛】L3-003 社交集群(并查集)
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友.一个“社交集群”是指部分兴趣爱好相同的人的集合.你需要找出所有的社交集群. 输入格式: 输入在第一行 ...
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...
- L3-003. 社交集群(并查集)
L3-003. 社交集群 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在社交网络平台注册时,用户通常会输入自己的兴趣爱好, ...
- L2-2 社交集群 (25 分)(一个写挫的并查集)
题目: 思路: 就是一个并查集的裸题,不过在数据查找方面可能不好处理,暴力完全可以解决这个问题啊!! #include <bits/stdc++.h> #include <cstdi ...
- PAT天梯赛 L1-049 天梯赛座位分配
题目链接:点击打开链接 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] ...
- PAT天梯赛L3-007 天梯地图
题目链接:点击打开链接 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至 ...
随机推荐
- 学习笔记:Kruscal 重构树
网上感觉没有什么很详细 + 证明的讲解啊) 前置:Kruskal 求最小生成树. 这个算法可以将一棵树 / 无向连通图重构成一颗有性质的新树. 算法可以解决一些树上瓶颈边权之类的问题,可以把需要持久化 ...
- AcWing 311 .月之谜
大型补档补了一年 题目链接 考虑枚举月之数的数列和,然后展开dp预处理 设当前模数为 \(P\) \(f[i][j][k]\) 表示一共有 i 位数字,数位和为 j,数值和 % P 的值为 K \(f ...
- 关于 SFML 在 Visual Studio下的环境搭建
SFML 全称 Simple and Fast Multimedia Library,它是一个开放源代码,跨平台,支持多种编程语言绑定,并且提供简单易用的接口,用于多媒体程序和游戏开发,是替代SDL的 ...
- 宝塔linux面板防护CC设置
使用宝塔linux面板很多用户受到CC攻击不知如何防范. 下面讲下如何利用宝塔自带的功能来进行基本的CC防护. 首先是在nginx上有个waf安全模块,里面有CC防护设置.(要求nginx为1.12版 ...
- 06-flask-文件上传案例
前端代码 Demo.html <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- Scala中的IO操作及ArrayBuffer线程安全问题
通过Scala对文件进行读写操作在实际业务中应用也比较多,这里介绍几种常用的方式,直接上代码: 1. 从文件中读取内容 object Main { def loadData(): Array[Stri ...
- Django使用channels实现Websocket连接
简述: 需求:消息实时推送消息以及通知功能,采用django-channels来实现websocket进行实时通讯.并使用docker.daphne启动通道,保持websocket后台运行 介绍Dja ...
- Shell----监控CPU/内存/负载高时的进程
Shell----监控CPU/内存/负载高时的进程 1.编写脚本 vim cpu-warning.sh #!/bin/bash #监控系统cpu的情况脚本程序 #取当前空闲cpu百份比值(只取整数部分 ...
- Numpy的学习6-深浅赋值(copy&deep copy)
# = 的赋值方式会带有关联性 import numpy as np a = np.arange(4) # array([0, 1, 2, 3]) b = a c = a d = b # 改变a的第一 ...
- 流程控制之☞ while 和 for 的故事
学习三连鞭... 什么是循环? 为什么要有循环? 如何用循环? 循环的基本语法:while 和 for 先来看while循环: while条件:首先得是个循环体. 1.如果条件为真,那么循 ...