zoj3641 Information Sharing 并查集+set

来源:互联网 发布:淘宝ios代退款店铺 编辑:程序博客网 时间:2024/05/27 00:31

    一间教室,起初是空的,有三种命令

1: "arrive Name m a1 a2 ..am"   名字为 Name的小朋友进来了,并且携带了m条信息,分别是a1,a2...am

2: "share Name1 Name2" 名字为Name1,Name2的小朋友分享他们的信息。

3: "check Name" 检查名字为Name的同学,并输出这个同学当前了解多少条不同的信息。

用map可以把名字hash成一个值,那么对每个小朋友可以用一个set来保存,合并的时候,名字之间的关系可以考虑用并查集存储,然后把set【A】的信息全部插入到set【B】中,那么一个集合里的人所了解的信息将会是同一个set。

两个注意的地方,

1:合并的时候可以直接循环一个set里的值,将其插入到父节点对应的set里,之后把这个集合清空,否则数据太大了会MLE..

2:由于存在share Name1 Name1,或者是这两个人当前已经在同一个集合里的情况,所以这里要判断一下,如果是同一个人或者是这两个人在同一个集合里,就continue掉。否则插入的时候自己往自己里面插元素等于没插,之后再一情况就错掉了= =...

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstring>#include <map>#include <set>using namespace std;typedef long long ll;const int maxn=201000;int n,m,k;int f[maxn];string s,s1,s2,cmd;int find(int x){    if (f[x]==x) return x;    else return f[x]=find(f[x]);}set<int>info[maxn];set<int>::iterator it;int ct;int main(){//    freopen("in.txt","r",stdin);    while(cin>>n)    {        memset(f,0,sizeof f);        ct=1;        map<string,int>hs;        hs.clear();        int id;        for (int i=1; i<=n; i++)        {            cin>>cmd;            if (cmd[0]=='a')            {                cin>>s;                if (hs.find(s)==hs.end())                {                    id=ct;                    info[id].clear();                    f[ct]=ct;                    hs[s]=ct++;                }                else id=hs[s];                cin>>m;                for (int i=0; i<m; i++)                {                    cin>>k;                    info[id].insert(k);                }            }            else if (cmd[0]=='s')            {                int id1,id2;                cin>>s1>>s2;                if (hs.find(s1)==hs.end())                {                    id1=-1;                }                else id1=hs[s1];                if (hs.find(s2)==hs.end())                {                    id2=-1;                }                else id2=hs[s2];                if (id1>=0 && id2>=0 && id1!=id2)                {                    id2=find(id2);                    id1=find(id1);                    if (id1==id2) continue;                    f[id2]=id1;                    for (it=info[id2].begin(); it!=info[id2].end(); it++)                    {                        info[id1].insert(*(it));                    }                    info[id2].clear();                }            }            else if (cmd[0]=='c')            {                cin>>s;                if (hs.find(s)==hs.end()) cout<<0<<endl;                else                {                    id=hs[s];                    id=find(id);                    cout<<info[id].size()<<endl;                }            }        }    }    return 0;}


0 0
原创粉丝点击