题意:不说了。。
思路:很明显的并查集。数据量比较小,集合可以用set维护。唯一一个值得注意的地方是可能会爆内存,因此每次合并以后原来的set要清空。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef long long LL;
int cnt;
map<string,int> mp;
const int maxn=100005;
int father[maxn];
set<int> s[maxn];
void init(int i)
{
father[i]=i;
}
int find(int p)
{
return p==father[p]?p:father[p]=find(father[p]);
}
void unio(int a,int b)
{
int fa=find(a),fb=find(b);
if(fa!=fb)
{
father[fa]=fb;
for(set<int>::iterator it=s[fa].begin(); it!=s[fa].end(); ++it)
{
s[fb].insert(*it);
}
s[fa].clear();
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
char a[20],b[20];
mp.clear();
cnt=0;
while(n--)
{
scanf("%s",a);
if(a[0]=='a')
{
scanf("%s",b);
mp[string(b)]=++cnt;
init(cnt);
s[cnt].clear();
int m;
scanf("%d",&m);
for(int i=0; i<m; ++i)
{
int x;
scanf("%d",&x);
s[cnt].insert(x);
}
}
else if(a[0]=='s')
{
char c[20];
scanf("%s%s",b,c);
int x=mp[string(b)],y=mp[string(c)];
unio(x,y);
}
else
{
scanf("%s",b);
int f=find(mp[string(b)]);
printf("%d\n",s[f].size());
}
}
}
return 0;
}