HDU__A - How Many Tables(第一天)

本文介绍了并查集数据结构的应用,包括初始化、合并集合、查找根节点和计算集合个数的方法,通过实例展示了如何使用并查集解决实际问题。

// 姿态1,:记录每个根结点子结点数

<span style="font-size:14px;">#include<stdio.h>
const int Max=1000;
int tab[Max+10];
int total[Max+10];
int find(int a){
    if(tab[a]!=a)
        tab[a]=find(tab[a]);
    return tab[a];
}
void Merge(int a,int b){
    int fx=find(a);
    int fy=find(b);
    if(fx==fy)
        return;
    tab[fx]=fy;
    total[fy]+=total[fx];
    total[fx]=1;
}
int main(){
    int T;
    while(scanf("%d",&T)!=EOF){
        for(int h=0;h<T;h++){
            int M,N;
            int sum=0,t,t1,cnt=0;
            scanf("%d%d",&N,&M);
            for(int i=0;i<N;i++){
               tab[i]=i;
               total[i]=1;
            }
            for(int i=0;i<M;i++){
               int h,s;
               scanf("%d%d",&h,&s);
               Merge((h-1),(s-1));
            }
            for(int i=0;i<N;i++)
                printf("%d ",tab[i]);
            printf("\n");
            for(int i=0;i<N;i++)
                printf("%d ",total[i]);
            printf("\n");
            for(int i=0;i<N;i++){
               if(total[i]!=1){
                  sum+=total[i];
                  cnt++;
               }
            }
            t=N-sum+cnt;
            printf("%d\n",t);
        }
    }
}</span>

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

<span style="font-size:14px;"><span style="background-color: rgb(240, 240, 240);">// 姿势2:初始化 集合个数,merge成功后-1</span>
</span>
<span style="font-size:14px;">#include<stdio.h>
const int Max=1000;
int tab[Max+10];
int find(int a){
    if(tab[a]!=a)
        tab[a]=find(tab[a]);
    return tab[a];
}
int main(){
    int T;
    while(scanf("%d",&T)!=EOF){
        for(int h=0;h<T;h++){
            int M,N;
            scanf("%d%d",&N,&M);
            int groups=N;
            for(int i=0;i<N;i++)
               tab[i]=i;
            for(int i=0;i<M;i++){
               int h,s;
               scanf("%d%d",&h,&s);
               int fx=find(h-1);
               int fy=find(s-1);
               if(fx!=fy){
                  tab[fx]=fy;
                  groups--;
               }
            }
            printf("%d\n",groups);
        }
    }
}
</span>


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

<span style="font-size:14px;">//姿势3:求根节点的个数,就是集合个数
</span>
<span style="font-size:14px;">#include<stdio.h>
const int Max=1000;
int tab[Max+10];
int find(int a){
    if(tab[a]!=a)
        tab[a]=find(tab[a]);
    return tab[a];
}
void Merge(int a,int b){
    int fx=find(a);
    int fy=find(b);
    if(fx==fy)
        return;
    tab[fx]=fy;
}
int main(){
    int T;
    while(scanf("%d",&T)!=EOF){
        for(int h=0;h<T;h++){
            int M,N;
            int cnt=0;
            scanf("%d%d",&N,&M);
            for(int i=0;i<N;i++)
               tab[i]=i;
            for(int i=0;i<M;i++){
               int h,s;
               scanf("%d%d",&h,&s);
               Merge((h-1),(s-1));
            }
            for(int i=0;i<N;i++){
               if(tab[i]==i){
                  cnt++;
               }
            }
            printf("%d\n",cnt);
        }
    }
}</span>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值