题目链接

题目描述:

输入
4
alice 2 alice@hihocoder.com alice@gmail.com
bob 1 bob@qq.com
alicebest 2 alice@gmail.com alice@qq.com
alice2016 1 alice@qq.com
输出
alice alicebest alice2016
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的父亲就对应着一个分组。

#include <map>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = * + ; int father[N];
int find(int id){
int fid = father[id];
if(fid==id) return fid;
return father[id]=find(fid);
}
void merge(int a,int b){
int fa = find(a);
int fb = find(b);
if(fa==fb) return;
father[fb] = fa;
} struct USER_MAILID{
char name[];
int mailId;
};
USER_MAILID names[]; vector<string > output_list[];
map<int,int> father_ouputId; int main(){
for(int i=;i<N;i++) father[i]=i; map<string,int> mail_id_mapper; int mailId = ; int n,cnt; cin>>n;
char strbuf[]; int id_buf[];
for(int id=;id<n;id++){
scanf("%s%d",names[id].name,&cnt);
for(int i=;i<cnt;i++){
scanf("%s",strbuf);
auto iter = mail_id_mapper.find(strbuf);
if(iter==mail_id_mapper.end()){
mail_id_mapper[strbuf] = (id_buf[i] = mailId++);
}
else{
id_buf[i] = iter->second;
}
}
names[id].mailId = id_buf[]; for(int i=;i<cnt;i++) for(int j=i+;j<cnt;j++){
merge(id_buf[i],id_buf[j]);
}
}
int curId = ; int outputId = ;
for(int id=;id<n;id++){
int f = find(names[id].mailId);
auto iter = father_ouputId.find(f);
if(iter==father_ouputId.end()){
father_ouputId[f] = curId = outputId++;
}
else curId = iter->second;
output_list[curId].push_back(names[id].name);
}
for(int i=;i<outputId;i++){
for(int j=;j<output_list[i].size();j++){
printf("%s ",output_list[i][j].c_str());
}puts("");
}
return ;
}

最新文章

  1. 二、JavaScript语言--JS基础--JavaScript进阶篇--选项卡切换效果
  2. 如何在CentOS 7上安装Percona服务器
  3. hibernate一对一关系实现
  4. solaris之复习
  5. Python中zip()函数用法
  6. Java基础知识强化之集合框架笔记06:Collection集合存储自定义对象并遍历的案例
  7. apache 配置网站目录,虚拟目录,新端口
  8. 从lca到树链剖分 bestcoder round#45 1003
  9. 【科普】什么是TLS1.3
  10. JDK 7中的文件操作的新特性
  11. php unicode编码和字符串互转
  12. echarts简单的折线图
  13. Android程序backtrace分析方法
  14. Visual Studio 2017 - Windows应用程序打包成exe文件(1)- 工具简单总结
  15. 《Linux内核原理与分析》第九周作业
  16. textarea输入框限制字数
  17. 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作
  18. sencha touch 可自动增长高度TextArea
  19. HTTPClient 超时链接设置
  20. NGUI 3.5教程(一)安装NGUI 3.5.8

热门文章

  1. 流式计算新贵Kafka Stream设计详解--转
  2. 【翻译】前景img-sprites, 高对比模式分析
  3. Windows2003 安装MVC4 环境的步骤
  4. OpenCart 如何安装 vQmod 教程
  5. 第十一章 Python之异常处理
  6. STL中的迭代器的使用
  7. 基于 OSGi 的面向服务的组件编程
  8. POJ 3517 And Then There Was One( 约瑟夫环模板 )
  9. 常用js方法封装
  10. javaScript 通过flie API读取本地文件