zoj 3641 并查集+set


题意:有一个教室 然后每个同学会知道一些信息 然后老师监视着他们 给出每次同学来的时候所获知的信息

然后操作有合并他们的信息 查询他们的信息


解法:直接并查集 然后信息用set搞一下,一直在想用set_union好还是直接写在find函数里面好(当然这个也不是很好)最后还是set直接暴力合并了 因为信息是可能重复的 这里的信息最多也就是100w 然后有一个优化就是合并的时候判断集合的大小 总是把小的并到大的上去 这样子就可以知道最多合并也就是100w了(当然我在代码里没有采用,因为感觉自己MMD)


#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<map>
#include<set>
using namespace std;
set<int>::iterator it;
char op[111],name[111],ano[111];
int f[111111],n,m,cnt,x;
int id,anoid;
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
int main(){
    map<string,int>df;
    set<int>s[111111];
    int _;
    while(~scanf("%d",&_)){
        df.clear();
        cnt=0;
        for(int i=1;i<=_;++i)f[i]=i,s[i].clear();
        
       while(_--){
           scanf("%s%s",op,name);
           if(*op=='c'){
               
               id=find(df[name]);
               printf("%d\n",(int)s[id].size());
               
           }else if(*op=='s'){
               
               scanf("%s",ano);
               id=df[name];anoid=df[ano];
               id=find(id);anoid=find(anoid);
               if(id==anoid)continue;
               
               
               while(!s[anoid].empty()){
                   it=s[anoid].begin();
                   s[id].insert(*it);
                   s[anoid].erase(it);
               }
               
               f[anoid]=id;
               
           }else if(*op=='a'){
               
               df[name]=++cnt;
               scanf("%d",&m);
               while(m--){
                   scanf("%d",&x);
                   s[cnt].insert(x);
               }
           }
       }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值