pta 05-树8 File Transfer (25分) c语言实现

提交图:

不了解并查集的百度下,不过这个不是典型的并查集吧。

提交图

具体代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100001
typedef struct Node
{
    int flag;  /*标记数,用来区分是否是一个集合里面的*/
    int data;
}BINCHA;
BINCHA h[MAX];
int da(int x,int y)
{
    return x>y?x:y;
}
int main()
{
    int i,j,m,can1,can2,qw[MAX];
    int u=0;
    char st;
    scanf("%d",&m);
    for(i=0;i<m;i++)/*初始化这个集合*/
    {
        h[i].data=i+1;
        h[i].flag=-1;
    }
    j=1;
    getchar();
    while(1)/*开始输入*/
    {
        scanf("%c",&st);
        if(st-'I'==0)/*判断第一个字符*/
        {
            scanf("%d %d",&can1,&can2);
            if((h[can1-1].flag==-1)&&(h[can2-1].flag==-1))/*如果这两个数的标识数都为-1,那都没有加入任何集合,那就加入一个集合*/
            {
                h[can1-1].flag=j;
                h[can2-1].flag=j;
                j++;
            }
            else if((h[can1-1].flag!=-1)&&(h[can2-1].flag==-1))
            {
                h[can2-1].flag=h[can1-1].flag;/*有一个加入了,另一个没有,并入一起*/
            }
            else if((h[can1-1].flag==-1)&&(h[can2-1].flag!=-1))
            {
                h[can1-1].flag=h[can2-1].flag;
            }
            else/*两个都加入了集合,将两个集合合并*/
            {
                if(h[can1-1].flag==h[can2-1].flag)
                    continue;
                else
                {
                    if(h[can1-1].flag>h[can2-1].flag)/*将标识数大的加入标记数小的集合里面*/
                    {
                        int fg;
                        fg =h[can1-1].flag;
                        for(int g=0;g<m;g++)
                        {
                            if(h[g].flag==fg)
                                h[g].flag=h[can2-1].flag;
                        }
                    }
                    else
                    {
                        int fg;
                        fg =h[can2-1].flag;
                        for(int g=0;g<m;g++)
                        {
                            if(h[g].flag==fg)
                                h[g].flag=h[can1-1].flag;
                        }
                    }
                }
            }
        }
        else if(st-'C'==0)
        {
            scanf("%d %d",&can1,&can2);
            if((h[can1-1].flag==h[can2-1].flag)&&((h[can1-1].flag!=-1)&&(h[can2-1].flag!=-1)))/*判断如果两个数的标记数相等qie不为负一就是联通的,数组存放这个值*/
                qw[u++]=1;
            else
                qw[u++]=0;
        }
        else if(st-'S'==0)
            break;
        getchar();
    }
    for(i=0;i<u;i++)/*输出no和yes*/
    {
        if(qw[i]==0)
            printf("no\n");
        else
            printf("yes\n");
    }
    int r,t,v,kl,as,sum;
    as=0;
    sum=0;
    v=1;
    r=h[0].flag;
    t=0;
    kl=1;
    while(1)
    {/*从1开始向后递增,每次对比标记数,当这个值为0时,就可以break出去*/
        for(i=0;i<m;i++)
        {
            if(h[i].flag==kl)
                as++;
        }
        sum=sum+as;
        if(as==0)
            break;
        t++;/*主要来判断还剩几个集合*/
        kl++;
        as=0;
    }
    if(sum!=m)/*如果相等就说明标记数中没有-1,不相等就有,就要加上1*/
        t++;
    for(i=0;i<m;i++)
    {
        if(h[i].flag==-1)/*是否有-1*/
            v=0;
    }
    if(t==1&&v==0)/*根据t与v输出*/
        printf("There are %d components.",m);
    else if(t!=1)
        printf("There are %d components.",t);
    else
        printf("The network is connected.");
    return 0;
}

第一次写csdn,代码不足请指出,我也在学习

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值