HDOJ -1272

在网上借鉴然后才写出来这个, 这个用到了压缩路径然后比之前的并查集多用到了一个flag来记录一些状态

添加visit数组来储存输入了多少数字,然后输入两个点时就对这两个点根节点查询,如果是就会形成环,输出no

在最后的判断然后要所有

#include<stdio.h>
#include<string.h>

int set[100001];
int visit[100001];
int flag;

int find_set(int i)
{
    int k,t;
    t=i;
    while(t!=set[t])          
        t=set[t];
    while(i!=t)          //修改路径---压缩
    {
        k=set[i];
        set[i]=t;
        i=k;
    }
    return i;
}

void merge(int i,int j)
{
    i=find_set(i);
    j=find_set(j);
    if(j==i)
        flag=1;
    else
        set[i]=j;
}

int main()
{
    int a,b,i,min,max;
    while(scanf("%d%d",&a,&b)&&(a!=-1||b!=-1))
    {
        memset(visit,0,sizeof(visit));
        visit[a]=visit[b]=1;
        flag=0;
        min=a<b?a:b;
        max=a>b?a:b;
        if(a==0&&b==0)        //测试数据为 0 0 时候注意要输出 Yes
        {
            printf("Yes\n");
            continue;
        }
        else if(a==b)
            flag=1;
        for(i=1;i<=100000;++i)
            set[i]=i;
        set[a]=b;
        while(scanf("%d%d",&a,&b)&&(a!=0||b!=0))
        {
            visit[a]=visit[b]=1;
            if(flag)
                continue;
            if(min>(a<b?a:b))
                min=a<b?a:b;
            if(max<(a>b?a:b))
                max=a>b?a:b;
            merge(a,b);
        }
        if(flag)
            printf("No\n");
        else                         //说明不存在回路
        {
            for(i=min;i<=max;++i)    //判断是否连通
            {
                if(visit[i]==0)      //没有出现的标号
                    continue;
                if(set[i]==i)
                    ++flag;
            }
            if(flag==1)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}   

的根节点都是一样的,才会都属于同一个集满足条件输出yes

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值