大致题意:
有三种操作 arrive用来表示某人知道的信息;share用来表示 两个人互相交流信息;check操作的时候,输出这个人知道的信息数量,操作的数量小于100000.
大致思路:
并查集+set去重。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<set>
using namespace std;
const int nMax=1000005;
int n,father[nMax],rank[nMax],N,M,num[nMax],sum; //rank近似树的高度。
int cnt,n1;
set<int>sset[nMax];
map<string,int>map1;
int getnum(string x){
if (map1.find(x)==map1.end()){
map1.insert(make_pair(x,cnt));
cnt++;
return cnt-1;
}else return map1[x];
}
int find(int x){ // 寻找父节点
if(x!=father[x])
return father[x]=find(father[x]);
return x;
}
void setunit(int x,int y)
{
set<int>::iterator iter;
for (iter = sset[x].begin(); iter != sset[x].end(); iter++)
{
sset[y].insert(*iter);
}
// sset[x].clear();
}
void unite(int a,int b){
int x=find(a);
int y=find(b);
if(x==y)
return ;
else{
if(rank[x]>rank[y]){
father[y]=x;
setunit(y,x);
}
else if(rank[x]<rank[y]){
father[x]=y;
setunit(x,y);
}
else{
father[x]=y;
setunit(x,y);
rank[y]++;
}
}
}
void init(){ // 初始化
int i;
for(i=0; i<nMax-1; i++){
father[i]=i;
rank[i]=0;
}
n=0;
sum=N;
}
int main(){
int num,a,b,c,d,i,j,k;
while(cin>>num){
map1.clear();
for(i=1;i<=nMax;i++)sset[i].clear();
init();
cnt=1;
char act[50];
string name;
while(num--){
cin>>act;
if(act[0]=='a'){
cin>>name;
cin>>a;
b=getnum(name);
for(i=0;i<a;i++)
{
cin>>c;
sset[b].insert(c);
}
continue;
}
if(act[0]=='s'){
cin>>name;
b=getnum(name);
cin>>name;
c=getnum(name);
unite(b,c);
continue;
}
if(act[0]=='c'){
cin>>name;
b=getnum(name);
cout<<sset[find(b)].size()<<endl;
}
}
}
return 0;
}