题目链接

题目描述:

  1. 输入
    4
  2. alice 2 alice@hihocoder.com alice@gmail.com
  3. bob 1 bob@qq.com
  4. alicebest 2 alice@gmail.com alice@qq.com
  5. alice2016 1 alice@qq.com
  1. 输出
    alice alicebest alice2016
  2. bob

如上所示,每一行前面是用户名,后面是他的邮箱,如果两个人共用了一个邮箱说明他是同一组的。

输出分组后的结果。一组占一行。组间顺序和组内顺序保证和输入相同。

数据大小是:最多10000个人,每个人最多10个email

The first line contains an integer N, denoting the number of usernames. (1 < N ≤ 10000)

Each username may have 10 emails at most.

-----------------------------------------------------------------------------------------------------------------------------------------

看着简单,还有有些细节需要注意的,比如顺序的保证。

上来就想建图求联通分量,想了一下没必要:如果每组都有10个email,则需要建边10*9*1w=90w条边,太麻烦了

后来一想用并查集做既省空间又省时间,每组的email都merge到每组的第一个上。这样每组的第一个email的父亲就对应着一个分组。

  1. #include <map>
  2. #include <cmath>
  3. #include <vector>
  4. #include <string>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <algorithm>
  10. using namespace std;
  11. const int N = * + ;
  12.  
  13. int father[N];
  14. int find(int id){
  15. int fid = father[id];
  16. if(fid==id) return fid;
  17. return father[id]=find(fid);
  18. }
  19. void merge(int a,int b){
  20. int fa = find(a);
  21. int fb = find(b);
  22. if(fa==fb) return;
  23. father[fb] = fa;
  24. }
  25.  
  26. struct USER_MAILID{
  27. char name[];
  28. int mailId;
  29. };
  30. USER_MAILID names[];
  31.  
  32. vector<string > output_list[];
  33. map<int,int> father_ouputId;
  34.  
  35. int main(){
  36. for(int i=;i<N;i++) father[i]=i;
  37.  
  38. map<string,int> mail_id_mapper; int mailId = ;
  39.  
  40. int n,cnt; cin>>n;
  41. char strbuf[]; int id_buf[];
  42. for(int id=;id<n;id++){
  43. scanf("%s%d",names[id].name,&cnt);
  44. for(int i=;i<cnt;i++){
  45. scanf("%s",strbuf);
  46. auto iter = mail_id_mapper.find(strbuf);
  47. if(iter==mail_id_mapper.end()){
  48. mail_id_mapper[strbuf] = (id_buf[i] = mailId++);
  49. }
  50. else{
  51. id_buf[i] = iter->second;
  52. }
  53. }
  54. names[id].mailId = id_buf[];
  55.  
  56. for(int i=;i<cnt;i++) for(int j=i+;j<cnt;j++){
  57. merge(id_buf[i],id_buf[j]);
  58. }
  59. }
  60. int curId = ; int outputId = ;
  61. for(int id=;id<n;id++){
  62. int f = find(names[id].mailId);
  63. auto iter = father_ouputId.find(f);
  64. if(iter==father_ouputId.end()){
  65. father_ouputId[f] = curId = outputId++;
  66. }
  67. else curId = iter->second;
  68. output_list[curId].push_back(names[id].name);
  69. }
  70. for(int i=;i<outputId;i++){
  71. for(int j=;j<output_list[i].size();j++){
  72. printf("%s ",output_list[i][j].c_str());
  73. }puts("");
  74. }
  75. return ;
  76. }

hiho 171周 - 水题,并查集的更多相关文章

  1. Uva 10596 - Morning Walk 欧拉回路基础水题 并查集实现

    题目给出图,要求判断不能一遍走完所有边,也就是无向图,题目分类是分欧拉回路,但其实只要判断度数就行了. 一开始以为只要判断度数就可以了,交了一发WA了.听别人说要先判断是否是联通图,于是用并查集并一起 ...

  2. Jzoj 初中2249 蒸发学水(并查集)

    题目描述 众所周知,TerryHu 是一位大佬,他平时最喜欢做的事就是蒸发学水. 机房的位置一共有n 行m 列,一开始每个位置都有一滴学水,TerryHu 决定在每一个时刻选择 一滴学水进行蒸发,直到 ...

  3. NYOJ--42--dfs水过||并查集+欧拉通路--一笔画问题

    dfs水过: /* Name: NYOJ--42--一笔画问题 Author: shen_渊 Date: 18/04/17 15:22 Description: 这个题用并查集做,更好.在练搜索,试试 ...

  4. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) A B C D 水 模拟 并查集 优先队列

    A. Broken Clock time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  5. C#LeetCode刷题-并查集

    并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列   39.3% 困难 130 被围绕的区域   30.5% 中等 200 岛屿的个数   38.4% 中等 547 朋友圈   45.1% ...

  6. luogu5012 水の数列 (并查集+线段树)

    如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了 然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x ...

  7. 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel

    有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...

  8. Codeforces Round #346 (Div. 2) E题 并查集找环

    E. New Reform Berland has n cities connected by m bidirectional roads. No road connects a city to it ...

  9. hiho #1066 : 无间道之并查集

    #1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 这天天气晴朗.阳光明媚.鸟语花香,空气中弥漫着春天的气息……额,说远了,总之,小Hi和小H ...

随机推荐

  1. 03《UML大战需求分析》之三

    学习了活动图之后,我又学习了流程分析工具之二的状态机图.看上去状态机图和活动图很类似,我也很容易从活动图的角度来理解状态机图.但是学习之后,发现两种图是两种完全不同的分析角度.活动图在流程分析时是玩你 ...

  2. VSCode Debug模式下各图标 含义

    按钮1:运行/继续 F5,真正的一步一步运行 按钮2:单步跳过(又叫逐过程) F10,按语句单步执行.当有函数时,不会进入函数. 按钮3:单步调试(又叫逐语句) F11:当有函数时,点击这个按钮,会进 ...

  3. JS判断客户端是否是iOS或者Android或者ipad(二)

    js判断客户端是IPAD和iphone 多了就不说了,直接上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22     funct ...

  4. CF1038D Slime 构造

    题目大意: 有nnn只史莱姆qwq,每只史莱姆有一个分数,每次一只史莱姆可以吞掉左边的或者右边的史莱姆(要是有的话),然后ta的分数会减去被吞的史莱姆的分数,问最后剩下的史莱姆分数最大为多少 输入格式 ...

  5. 路飞学城Python-Day35

    08-初识SQL语句 数据库客户端操作的内容(增查改删): 1.操作数据库 操作数据库 增(本质上就是创建一个本地文件夹) create database db1 charset utf8; 查 查看 ...

  6. JS实现HTML打印机效果

    5月最近在学Django,所以所有的Demo都没有PO出去 <!DOCTYPE html> <html lang="en"> <head> &l ...

  7. Pyhton学习——Day59

    参考博客: http://www.cnblogs.com/wupeiqi/articles/6144178.html Form 1. 验证 2. 生成HTML(保留上次输入内容) 3. 初始化默认是 ...

  8. 深度学习之入门Pytorch(1)------基础

    目录: Pytorch数据类型:Tensor与Storage 创建张量 tensor与numpy数组之间的转换 索引.连接.切片等 Tensor操作[add,数学运算,转置等] GPU加速 自动求导: ...

  9. HDU 1558 Segment set( 判断线段相交 + 并查集 )

    链接:传送门 题意:输入一个数 n 代表有 n 组操作,P 是在平面内加入一条线段,Q x 是查询第 x 条线段所在相交集合的线段个数 例如:下图 5 与 1.2 相交,1 与 3 相交,2 与 4 ...

  10. BZOJ 1576 [USACO]安全路经Travel (树剖+线段树)

    题目大意: 给你一张无向图,求1到其他节点 不经过最短路的最后一条边 的最短路长度,保证每个节点的最短路走法唯一 神题,$USACO$题目的思维是真的好 先$dijkstra$出最短路树 对于每个节点 ...