码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2473 Junk-Mail Filter(并查集)

时间:2015-03-12 14:40:11      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:

题意:

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\n",++T,ans);
    }

    return 0;
}

 

hdu 2473 Junk-Mail Filter(并查集)

标签:

原文地址:http://www.cnblogs.com/fish7/p/4332142.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!