并查集的简单应用——HDU

#include<cstdio>
#include<cstring>
using namespace std;
const int MAX_N =1011;
int par[MAX_N];
int rank1[MAX_N];
void init(int n)
{
    for(int i=1; i<=n; i++)
    {
        par[i]=i;
        rank1[i]=0;
    }
}
int find1(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find1(par[x]);
}
void unite(int x,int y)
{
    x=find1(x);
    y=find1(y);
    if(x==y)
        return;
    if(rank1[x]<rank1[y])
        par[x]=y;
    else
    {
        par[y]=x;
        if(rank1[x]==rank1[y]) rank1[x]++;
    }
}
bool same(int x,int y)
{
    return find1(x)==find1(y);
}
int main()
{
    int kase;
    scanf("%d",&kase);
    while(kase--)
    {
        memset(par,0,sizeof(par));
        memset(rank1,0,sizeof(rank1));
        int n,s,x,y,ans=0;
        scanf("%d%d",&n,&s);
        init(n);
        for(int i=0; i<s; i++)
        {
            scanf("%d%d",&x,&y);
            unite(x,y);
        }
        for(int i=1;i<=n;i++)
            if(par[i]==i)
            ans++;
        printf("%d\n",ans);
    }
}
并查集的简单应用,注意边界,注意清空。
套了模板,没有注意边界,错了多次。
我看到的优秀代码http://www.cnblogs.com/liaoguifa/archive/2012/12/17/2821690.html
<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
int father[1002];

int find(int n)
{
    if(father[n] == n) return n;
    else return father[n] = find(father[n]);
}

int main()
{
    int n, m, T, x, y, cnt, i, j;
    scanf("%d", &T);
    while(T--)
    {
        cnt = 0;
        scanf("%d%d", &n, &m);
        for(i=0; i<n; ++i) father[i] = i;
        for(i=0; i<m; ++i) 
        {
            scanf("%d%d", &x, &y);
            x = find(x-1), y = find(y-1);
            if(x != y) father[x] = y;
        }
        for(i=0; i<n; ++i) if(father[i] == i) cnt++;
        printf("%d\n", cnt);
    }
    return 0;
}


 
 

你可能感兴趣的:(并查集的简单应用——HDU)