ACM-Hdu-1272-小希的迷宫


此题是一个思想简单, 实现困难的题,因为有很多的小情况

1.    首先--判断集合是否有环--用并查集    --->   新加入一条边的时候

 if( find(a) != find(b) )//判断结果2
                        Union(a, b);
                else    //若果在未加入时,  发现发现已加入的点与未加入的点同根, 则说明图中有环
                {
                        init();
                        printf("No\n");
                        while( scanf("%d%d", &a, &b) && a+b){   }
                        continue;
                }

2.  如果直到 0 0, 碰到一组数据结束, 不能说明符合条件!!!

不能说明符合条件!!!

不能说明符合条件!!!

重要的事情说三遍,    不符合是因为,如果之前输入的数据,     组成了若干个不相连的集合,  那么之前的同根判断会做出错误的判断

所以要判断图的连通性,代码如下:

void only_one_gater()
{
        int cnt  = 0;

        for(int i = 1; i <= temp; ++i)
        {
                if(pre[i] == i && vis[i] == true)//若果vis标记到,某个点曾经出现过, 而且这个点位根节点,则cnt++
                {
                        cnt++;
                }
                if(cnt > 1) 说明有好几个不连通的集合
                {
                        printf("No\n");
                        return;
                }
        }
        printf("Yes\n");
}

完整代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 100100
using namespace std;
int a, b, temp;
int pre[maxn];
bool vis[maxn];

void init()
{
        for(int i = 0; i < maxn; ++i)
                pre[i] = i;
         fill(vis, vis+maxn, false);
         temp = -1;
}

int find(int& index)
{
        return pre[index] = pre[index] == index?index: find(pre[index]);
}

void Union(int& a, int& b)
{
        pre[find(a)] = find(b);
}

void only_one_gater()
{
        int cnt  = 0;

        for(int i = 1; i <= temp; ++i)
        {
                if(pre[i] == i && vis[i] == true)
                {
                        cnt++;
                }
                if(cnt > 1)
                {
                        printf("No\n");
                        return;
                }
        }
        printf("Yes\n");
}

int main()
{
        init();
        while( ~scanf("%d%d", &a, &b) )
        {
                vis[a] = vis[b] = true;
                temp = max(a,max(b,temp));
                if(a+b == 0)        //一组结束,得出结果1
                {
                        only_one_gater();
                        init();
                        continue;
                }
                if(a + b == -2)        //全部结束
                        return 0;

                if( find(a) != find(b) )    //判断结果2
                        Union(a, b);
                else
                {
                        init();
                        printf("No\n");
                        while( scanf("%d%d", &a, &b) && a+b){   }
                        continue;
                }
        }
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值