• hdu2473 JunkMail Filter(并查集)


    题意:给定n个点,刚进行两种操作,将两个点合并,以及将一个点孤立,问最后点有几堆

    分析:删除一个点,只是将该点独立起来,或者说将该点从所在集合中脱离,而所在集合的结构不变,若真的将该点从集合中删去,会带来很多不必要的麻烦,所以,可以反而添加一个虚拟的点代替独立出来的点,这样,用一个数组将每一个点都映射到一个虚拟的点上,之后在虚拟的点上面操作即可。当要独立一个点时,只需将该点映射到另一个原先不存在的点即可。

    之后,统计集合个数有俩种方法,一个是根据集合含有的元素的个数,另一个则是统计根节点的个数。

    其一
    #include<iostream>
    #include<algorithm>
    #define M 1000000+10
    using namespace std;
    int f[M],n,m;
    int hash1[M],r[M];
    void init()
    {
    for(int i=0;i<M;i++)
    {
    f[i]=i;
    hash1[i]=i;
    r[i]=1;
    }
    }
    int find(int x)
    {
    if(x==f[x])
    return f[x];
    f[x]=find(f[x]);
    return f[x];
    }
    void Union(int x,int y)
    {
    int a=find(x);
    int b=find(y);
    if(a==b) return ;
    if(r[a]>r[b])
    {
    f[b]=a;
    r[a]+=r[b];
    r[b]=0;
    }
    else {
    f[a]=b;
    r[b]+=r[a];
    r[a]=0;
    }
    }
    int main()
    {
    int cas=0,a,b;
    char str[5];
    while(scanf("%d %d",&n,&m)==2 &&(n||m))
    {
    init();
    while(m--)
    {
    scanf("%s",str);
    if(str[0]=='S')
    {
    scanf("%d",&a);
    r[find(hash1[a])]--;
    hash1[a]=n++;
    }
    else {
    scanf("%d %d",&a,&b);
    Union(hash1[a],hash1[b]);
    }
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
    if(r[i]>0)
    ans++;
    }
    printf("Case #%d: %d\n",++cas,ans);
    }
    return 0;
    }
    其二
    #include<iostream>
    #include<algorithm>
    #include<set>
    using namespace std;
    int f[1000001],n,m;
    int hash1[100001];
    set<int> st;
    void init()
    {
    for(int i=0;i<n;i++)
    {
    f[i]=i;
    hash1[i]=i;
    }
    }
    int find(int x)
    {
    if(x==f[x])
    return f[x];
    f[x]=find(f[x]);
    return f[x];
    }
    void Union(int x,int y)
    {
    int a=find(x);
    int b=find(y);
    if(a==b) return ;
    f[a]=b;
    }
    int main()
    {
    int cas=0,a,b;
    char str[5];
    while(scanf("%d %d",&n,&m)==2 &&(n||m))
    {
    init();
    st.clear();
    int num=n;
    while(m--)
    {
    scanf("%s",str);
    if(str[0]=='S')
    {
    scanf("%d",&a);
    hash1[a]=num++;
    f[hash1[a]]=hash1[a];
    }
    else {
    scanf("%d %d",&a,&b);
    Union(hash1[a],hash1[b]);
    }
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
    // printf("%d %d\n",hash1[i],find(hash1[i]));
    st.insert(find(hash1[i]));
    }
    printf("Case #%d: %d\n",++cas,st.size());
    }
    return 0;
    }



  • 相关阅读:
    RMAN01009: syntax error: found "dot" 解决方法
    Oracle 11g 新特性 DB_ULTRA_SAFE 参数 说明
    Oracle 11g 新特性 Result Cache(结果高速缓存)说明
    Oracle 11g 新特性 DB_ULTRA_SAFE 参数 说明
    /dev/sdxx is apparently in use by the system; will not make a filesystem here! 解决方法
    CSDN博客之星 投票说明
    Oracle 11g 新特性 – ACFS 说明
    Oracle 与 iptables 和 SELinux 禁用关系 说明
    Vbox 安装 windows Server 2008 R2 报错 Info: An unexpected error has occurred 解决方法
    Oracle 11g 新特性 SecureFiles 说明
  • 原文地址:https://www.cnblogs.com/nanke/p/2351778.html
Copyright © 2020-2023  润新知