zoukankan      html  css  js  c++  java
  • hdu 2473 Junk-Mail Filter(并查集)

    题意:

    N个邮件需要鉴别。

    两种操作:

    1. M X Y:X和Y是同一种邮件

    2.S X:X被误判(意味着X要被它从属的那个集合“踢出去"而所有其它的邮件的关系保持不变)

    问最后总共有几种邮件。

    思路:

    用并查集可以实现邮件的“合并”。但是要把单独的X“踢出去”,然后又要保证其它的关系不变。

    弄个双层结构,第一层结构是用来描述邮件之前的关系的。第二层结构是用来指向第一层的结点。

    第一层是fa,第二层是vfa。当X被“踢出去”时,只要在第一层中新加一个点,然后vfa[x]指向这个新结点即可。

    既保留了原来的邮件之前的关系,又顺利地把X“踢出去”了。

    代码:

    int n,m;
    int fa[1200005];
    int vfa[100005];
    
    
    int findFa(int x){
        return fa[x]==x?fa[x]:fa[x]=findFa(fa[x]);
    }
    
    
    
    int main(){
    
        int T=0;
        while(scanf("%d%d",&n,&m),n||m){
            rep(i,1,n){
                fa[i]=i;
                vfa[i]=i;
            }
            int cn=n;
    
            while(m--){
                char ope[5];
                scanf("%s",ope);
                if(ope[0]=='M'){
                    int a,b;
                    scanf("%d%d",&a,&b);
                    int fx=findFa(vfa[a+1]);
                    int fy=findFa(vfa[b+1]);
                    if(fx!=fy){
                        fa[fx]=fy;
                    }
                }else{
                    int x;
                    scanf("%d",&x);
                    vfa[x+1]=++cn;
                    fa[cn]=cn;
                }
            }
            map<int,int> mp;
            mp.clear();
    
            int ans=0;
    
            rep(i,1,n){
                int t=findFa(vfa[i]);
                if(mp[t]==0){
                    mp[t]=1;
                    ++ans;
                }
            }
            printf("Case #%d: %d
    ",++T,ans);
        }
    
        return 0;
    }
  • 相关阅读:
    S3:代理模式 Proxy
    S2:外观模式 Facade
    S1:适配器 Adapter
    C5:单例模式 Singleton
    C4:原型模式 Prototype
    C3:建造者模式 Builder
    C2:抽象工厂 Abstract Factory
    C1:工厂模式 Factory
    设计模式分类
    数据访问对象模式
  • 原文地址:https://www.cnblogs.com/fish7/p/4332142.html
Copyright © 2011-2022 走看看