hihocoder #1335 : Email Merge(map+sort)

传送门

题意

分析

每次插入人名与邮箱的时候,做一次并查集,然后做一次sort即可

trick

3
a 1 first@hihocoder.com
b 1 second@hihocoder.com
c 2 first@hihocoder.com second@hihocoder.com

代码

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))

int n,m;
struct node
{
   int depth,fa;//节点深度及父亲/编号
   string name;
   node(const string &str,int depth,int id):name(str),depth(depth),fa(id){}
   bool operator<(const node &p)const
   {
      return (fa==p.fa)?depth<p.depth:fa<p.fa;//按父亲排序,再按深度排序
   }
};
vector<node>point;//记录所有的点
int find(int u){ return (point[u].fa==u)?u:point[u].fa=find(point[u].fa); }
void merge(int u,int v)
{
   int fu=find(u),fv=find(v);
   if(fu!=fv)
   {
      if(point[fu].depth>point[fv].depth) swap(fu,fv);
   }
   point[fv].fa=fu;
}
char buf[10010];
unordered_map<string,int>mp;//hash_map返回字符串对应的id
int get_id(const string &buf,int time)//获取id
{
   if(mp.count(buf)) return mp[buf];
   int sz=mp.size();
   point.push_back(node(buf,time,sz));
   return mp[buf]=sz;
}
vector<int>user;
int main()
{
   scanf("%d",&n);
   int tot=0;
   F(i,1,n)
   {
      scanf("%s",buf);
      int u=get_id(buf,tot++);
      user.push_back(u);
      scanf("%d",&m);
      F(j,1,m)
      {
         scanf("%s",buf);
         int v=get_id(buf,tot++);
         merge(u,v);//将人名与邮箱相连接
      }
   }
   for(auto u:user) find(u);//对于每个人名都做一次并查集
   vector<node>ans;  
   for(auto u:user) ans.push_back(point[u]);
   sort(ans.begin(),ans.end());//排序
   for(int u=0;u<n;++u)
   {
      printf("%s",ans[u].name.c_str() );
      if(u<n-1&&ans[u].fa==ans[u+1].fa) putchar(' ');
      else putchar('\n');
   }
   return 0;
}
posted @ 2017-10-16 12:10  遗风忘语  阅读(171)  评论(0编辑  收藏  举报