ZOJ3641 Information Sharing

来源:互联网 发布:局域网限速软件app 编辑:程序博客网 时间:2024/06/05 07:19

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4809


题意:

给出order数n

给出n行order<3种>

第一种:travel A m a1 .. ai .. an表示来了同学A 其中知道m个信息 信息号为a1 .. ai .. an..

第二种:share A B表示 A和B同学分享了她们共有的信息..其中信息可传递..并且和share先后无关..

第三种:check A 表示问A同学知道了多少条信息


思路:

用map<string, int> 来让同学名字变成序号..

share则使用并查集,对人名使用并查集。share时合并则使用set的插入,优化:让size小的插入size大的。


#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <set>#include <vector>#include <iostream>#include <algorithm>#include<string>using namespace std;//const double eps=1e-7;//const double INF=1e50;//const double pi=acos(-1);#define N 100005#define M 1000005int f[N],n,people;char order[10],name1[20],ch,name2[20];string na,nb;map<string,int> a;map<int,int> info;set<int> b[N];int root(int s){    if (f[s]==s) return s;    f[s]=root(f[s]);    return f[s];    /*int temp=s;    while(f[temp]!=temp)temp=f[temp];    while(f[s]!=s){s=f[s];f[s]=temp;}    return temp;*/}int main(){    //freopen("a","r",stdin);    int i,m,j,k,in;    while (scanf("%d",&n)!=EOF)    {        a.clear();        for (i=0;i<n;i++) b[i].clear();        info.clear();        people=0;        in=0;        for (i=1;i<=n;i++)        {            gets(name1);            scanf("%s %s",order,name1);            na=name1;            if (order[0]=='a')            {                a[na]=people;                f[people]=people;                scanf(" %d",&m);                map<int,int>::iterator it;                int ss;                for (j=1;j<=m;j++)                {                    scanf("%d",&k);                    it=info.find(k);                    if (it==info.end())                    {                        in++;                        info[k]=in;//不要写反了                        ss=in;                    }                    else ss=(*it).second;                    b[people].insert(ss);                }                people+=1;            }            else if (order[0]=='s')            {                int n1,n2,n3;                scanf(" %s",name2);                nb=name2;                map<string,int>::iterator it;                it=a.find(na);                n1=(*it).second;                it=a.find(nb);                n2=(*it).second;                n1=root(n1);//找根不可缺少                n2=root(n2);                if (n1==n2) continue;                if (b[n1].size()<b[n2].size())                {                    n3=n1;                    n1=n2;                    n2=n3;                }                set<int>::iterator it1;                for (it1=b[n2].begin();it1!=b[n2].end();it1++) b[n1].insert(*it1);                b[n2].clear();                f[n2]=n1;            }            else            {                int n1;                map<string,int>::iterator it;                it=a.find(na);                n1=(*it).second;                n1=root(n1);                printf("%d\n",b[n1].size());            }        }    }    return 0;}