ZOJ Monthly, August 2012 3641 Information Sharing

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3641

题意:有三种操作:
1)arrive Name m a1 a2 ..a:名字为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;
}

 

posted on 2012-08-26 21:38  aigoruan  阅读(191)  评论(0)    收藏  举报

导航