hdu1272 小希的迷宫

本文介绍如何使用并查集算法解决图的连通性和判断是否存在环的问题,详细解释了并查集的基本原理和应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接

解题思路:题目意思是找到判断是不是连通无环的图,首先想到的就是并查集。

              判断成环的时候,只要判断输入边的两个点。有一个共同的父节点,那么这两个点就成环。

              判断连通的时候,只要判断根节点数为1即可。

     

正确代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define M 100008
int f[M],tot,cur;
int find (int x)
{
    return f[x] == x ? x : f[x] = find(f[x]);
}
void make(int a,int b)
{
    int x=find(a);
    int y=find(b);
    if(x==y)
        tot=1;
    else
        f[y]=x;
}
int main()
{
    int a,b;
    while(1)
    {
        memset(f,0,sizeof(f));
        tot=0;cur=0;
        while(scanf("%d%d",&a,&b)!=EOF&&a&&b)
       {
        if(a==-1&&b==-1) return 0;
        if(a==b) continue;
         if(f[a]==0)
              f[a]=a;
        if(f[b]==0)
              f[b]=b;
            make(a,b);
     }
        for(int i=1;i<M;i++)
            if(f[i]==i)
                cur++;
            if(cur>1||tot==1)
                printf("No\n");
            else
                printf("Yes\n");

    }
    return 0;
}
错误代码如下:

Runtime Error (STACK_OVERFLOW) (因为
递归层数过多;没有在全局开比较大的数组;这些会出现STACK_OVERFLOW
)这个错误就是递归层数太多

 #include<iostream>
 using namespace std;
 #define MAX 100005
 int father[MAX],flag,sign[MAX];
 int FindSet(int z)
{
    return father[z]==z?z:father[z]=FindSet(father[z]);
}

 void Union(int x,int y)
 {
     x=FindSet(x);
     y=FindSet(y);
     if(x!=y)
         father[x]=y;// y是x的父节点
     else flag=0;    //同父节点,成环
 }

 int main()
 {
     int i,a,b;
     while(cin>>a>>b)
     {
         if(a==-1&&b==-1) break;
         if(a==0&&b==0)
         {
             cout<<"Yes"<<endl;
             continue;
           }
         for(i=1;i<MAX;i++)
         {
             father[i]=i;
             sign[i]=0;
         }
         sign[a]=sign[b]=1;
         flag=1;
         Union(a,b);
         while(cin>>a>>b)
         {
            if(a==0&&b==0) break;
             Union(a,b);
             sign[a]=sign[b]=1;
         }
         int k=0;
         for(i=1;i<MAX;i++)
         {
             if(sign[i]&&father[i]==i)   //判断根节点k数目
                 k++;
             if(k>1) flag=0;
         }
         if(flag) cout<<"Yes"<<endl;
         else cout<<"No"<<endl;
     }
     return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值