HDU 2473 并查集

来源:互联网 发布:校园网限制mac地址 编辑:程序博客网 时间:2024/05/01 10:35

点击打开链接

题意:给了两种操作,M u v将u与v连接到一起,S u 将u从它的集合中拿出来,但是不改变集合中的其他元素已有的关系

思路:就是直接并查集,然后有了个删点的操作,这与之前写的ZOJ 3789的删除操作是一样的,找个数组代替就可以了,简单~~~  PS:加了路径压缩跑得还是那么慢,org

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INT=0x3f3f3f3f3f3f3f3fll;const int maxn=1100010;int f[maxn],ff[maxn];int find1(int x){    int k,r,j;    r=x;    while(r!=f[r]) r=f[r];    k=x;    while(k!=r){        j=f[k];        f[k]=r;        k=j;    }    return r;}void unite(int a,int b){    int aa=find1(a);    int bb=find1(b);    if(aa==bb) return ;    f[aa]=bb;}int vis[maxn];int main(){    int n,m,u,v,cas=1;    char ch[10];    while(scanf("%d%d",&n,&m)!=-1){        if(n==0&&m==0) break;        for(int i=0;i<=n+m;i++){            f[i]=ff[i]=i;vis[i]=0;        }        int ans=n,sum=0;        for(int i=0;i<m;i++){            scanf("%s",ch);            if(ch[0]=='M'){               scanf("%d%d",&u,&v);               unite(ff[u],ff[v]);            }else if(ch[0]=='S'){                scanf("%d",&u);                ff[u]=n++;f[n]=n;            }        }        for(int i=0;i<ans;i++){            int t=find1(ff[i]);            vis[t]=1;        }        for(int i=0;i<n;i++) if(vis[i]) sum++;        printf("Case #%d: %d\n",cas++,sum);    }    return 0;}

0 0