并查集

来源:互联网 发布:网络教育文凭和函授 编辑:程序博客网 时间:2024/05/18 18:04

并查集主要运用于一些带有连带关系的题目。

比如说,A是B的朋友,B是C的朋友。那么A是C的朋友。给你一系列的人,和这些人之间的关系。

然后让你求一共有多少个关系,或者A,B之间是否存在关系。

也可运用于一些点,求最少需要几个边才能形成一张连通图~

运用步骤:

初始化

  把每个点所在集合初始化为其自身。
  通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N)。

查找

  查找元素所在的集合,即根节点。

合并

  将两个元素所在的集合合并为一个集合。
  通常来说,合并之前,应先判断两个元素是否属于同一集合,这可用上面的“查找”操作实现。

样例分析:

HUD1232

#include<stdio.h>int town[1001];int get(int x){    while(town[x]!=x)        x=town[x];    return x;}void pan(int x,int y){    x=get(x);    y=get(y);    if(x!=y)    {        town[y]=x;    }}int main(){    int sum,i,m,n,a,b;    while(scanf("%d",&n)&&n)    {        scanf("%d",&m);        for(i=1;i<=n;i++)        {            town[i]=i;        }        for(i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            pan(a,b);        }        sum=0;        for(i=1;i<=n;i++)        {            if(town[i]==i)            sum++;        }        printf("%d\n",sum-1);    }    return 0;}

HDU 1272


#include<stdio.h>int point[200000];int sum[200000];int leap;int get(int x){    while(point[x]!=x)        x=point[x];    return x;}void pan(int x,int y){    x=get(x);    y=get(y);    if(x==y)        leap=1;    else    {        point[y]=x;    }}int main(){    int m,n,i,leapp;    while(scanf("%d%d",&n,&m)&&((n+1)||m+1))    {        leap=0;        for(i=0;i<=100000;i++)point[i]=i,sum[i]=0;        sum[n]=1;        sum[m]=1;        if(m||n)pan(n,m);        else        {            printf("Yes\n");            continue;        }        while(scanf("%d%d",&n,&m)&&(n||m))        {            pan(n,m);            sum[n]=1;            sum[m]=1;        }        leapp=0;        for(i=1;i<=100000;i++)        {            if(sum[i]==1&&point[i]==i)            leapp++;        }        if(leapp==1&&leap==0)        printf("Yes\n");        else        printf("No\n");    }    return 0;}

POJ 1611

#include<stdio.h>int point[50000];int find(int x){    while(point[x]!=x)        x=point[x];    return x;}void pan(int x,int y){    x=find(x);    y=find(y);    if(x!=0&&y!=0)    {        if(x!=y)        {            point[y]=x;        }    }    else if(x==0&&x!=y)    {        point[y]=x;    }    else if(y==0&&x!=y)    {        point[x]=y;    }}int main(){    int leap,m,n,i,a,b,c,j;    while(scanf("%d%d",&n,&m)&&(m||n))    {        for(i=0;i<n;i++)        {            point[i]=i;        }        for(i=0;i<m;i++)        {            scanf("%d",&a);            scanf("%d",&b);            for(j=1;j<a;j++)            {                scanf("%d",&c);                pan(b,c);            }        }        leap=0;        for(i=0;i<n;i++)        {            if(find(i)==0)                leap++;        }        printf("%d\n",leap);    }    return 0;}



原创粉丝点击