并查集解1335 : Email Merge(hihocoder)

题目

描述

You are given a list of usernames and their email addresses in the following format:

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

Your task is to merge the usernames if they share common email address:

alice alicebest alice2016

bob

输入

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

The following N lines contain N usernames and their emails in the previous mentioned format.

Each username may have 10 emails at most.

输出

Output one merged group per line.

In each group output the usernames in the same order as the input.

Output the groups in the same order as their first usernames appear in the input.

样例输入

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

题目解析

题目给定n个人,每个人使用不多于10个的邮箱,要求找出共享邮箱的人(比如a使用123@qq.com, b使用345@qq.com和123@qq.com, c使用345@qq.com,则a,b,c共享邮箱),要求找出这些类的人并按照输入顺序输出

思路解析

这就是并查集的简单使用样例,直接套入并查集的代码即可,注意要使用STL容器存储相关信息,以增快速率,比如用map存储邮箱以及该邮箱的使用者,这样能增加遍历速度,不然就可能出现TLE的情况

AC代码

//
// Created by YoshiPark on 2017/10/16.
//

#include <iostream>
#include <vector>
#include <map>
using namespace std;
int F[10010];
void init(int num) {
    for (int i = 0; i < num; ++i) {
        F[i] = i;
    }
}
int getfather(int v) {
    if (v == F[v]) {
        return v;
    } else{
        F[v] = getfather(F[v]);
        return F[v];
    }
}
int merge(int a, int b) {
    int fa = getfather(a);
    int fb = getfather(b);
    if (fa != fb) {
        if (fa > fb) {
            F[fa] = fb;
        } else{
            F[fb] = fa;
        }
    }
}

int main() {
    int num;
    cin >> num;
    init(num);
    map<string, vector<int>> maillist;
    vector<string> userlist;
    for (int i = 0; i < num; ++i) {
        string username;
        int mailnum;
        cin >> username >> mailnum;
        userlist.push_back(username);
        for (int j = 0; j < mailnum; ++j) {
            string mail;
            cin >> mail;
            maillist[mail].push_back(i);
        }
    }
    for (auto it = maillist.begin(); it !=  maillist.end(); ++it) {
        for (int j = 1; j < it->second.size(); ++j) {
            merge(it->second[0],  it->second[j]);
        }
    }
    vector<int> group[10010];
    for(int i = 0; i< num; i++){
        if(getfather(i) != i) group[getfather(i)].push_back(i);
    }
    for(int i = 0; i< num; i++){
        if(getfather(i) == i){
            cout<< userlist[i];
            for(int j = 0; j<group[i].size(); j++){
                cout<<" "<< userlist[group[i][j]];
            }
            cout<<endl;
        }
    }
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值