ZOJ Monthly, August 2012 3641 Information Sharing
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3641
题意:有三种操作:
1)arrive Name m a1 a2 ..am :名字为Name的人到达,带有m个信息:a1 a2 ..am(m<=10)
2)share Name1 Name2:Name1和Name2共享信息(注意是一直共享的)
3)check Name:检查Name拥有的信息,并要求输出。
信息最多1000个,现有n个这些操作。
思路:并差集,将共享信息的人弄成一个连通分量,并合并信息。
View Code
#include<stdio.h> #include<string.h> #include<iostream> #include<set> #include<map> #include<string> using namespace std; const int maxn = 100005; int fa[maxn],tp; set<int>as[maxn]; map<string,int>sa; int fin(int x) { if(fa[x]!=x)fa[x]=fin(fa[x]); return fa[x]; } void fun(int x,int y) { int xx = fin(x); int yy = fin(y); if(xx^yy){ if(as[xx].size()<as[yy].size()) yy^=xx^=yy^=xx; fa[yy]=fa[xx]; set<int>::iterator pos; for(pos=as[yy].begin(); pos!=as[yy].end();pos++) as[xx].insert(*pos); } } int main() { char a[100],b[100]; int i,j,k,t,n; while(scanf("%d",&n)==1){ tp = 0; for(i = 1; i <= n; ++ i){ as[i].clear(); fa[i] = i; } while(n--){ scanf("%s",a); if(a[0]=='a'){ scanf("%s%d",a,&k); sa[a] = ++tp; for(i = 0; i < k; ++ i){ scanf("%d",&j); as[tp].insert(j); } }else if(a[0]=='s'){ scanf("%s%s",a,b); k = fin(sa[a]); t = fin(sa[b]); fun(k,t); }else{ scanf("%s",a); k = sa[a]; printf("%d\n",as[fin(k)].size()); } } } return 0; }

浙公网安备 33010602011771号