poj 1308 Is It A Tree?(并查集)

题意:给出一系列的点,前者指向后者,求是否是一棵树。

思路:并查集思想,主要注意以下几组数据
1: 0 0 空树是一棵树

2: 1 1 0 0 不是树 不能自己指向自己
3: 1 2 1 2 0 0 不是树....自己开始一直在这么WA 好郁闷 重复都不行呀~~5555
4: 1 2 2 3 4 5 0 0 不是树 森林不算是树(主要是注意自己) 5: 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1 注意 一个节点在指向自己的父亲或祖先 都是错误的 即 9-->1 错
6: 1 2 2 1 0 0 也是错误的
#include <stdio.h>
#define M 10000
int a[M],b[M];
int flag;
int find (int v)
{
      int t;
      t = v;
      while (t != a[t])
              t = a[t];
      return t;
}
void Union (int x,int y)
{
      if (y != a[y])        //如果结点编号不等于本身,说明有两条边指向它
      {
              flag = 1;
              return ;
      }
      int v1,v2;
      v1 = find (x);
      v2 = find (y);
      if (v1 == v2)      //两个点的根结点相等 说明形成了环或本身指向本身
      {
              flag = 1;
              return ;
      }
      if (v1 != v2)
              a[v2] = v1;
}


int main ()
{
      int x,y,i,j;
      int count = 1;

      while (1)
      {
              flag = 0;
              j = 0;
              for (i = 0; i < M; i ++)
                      a[i] = i;
              scanf ("%d %d",&x,&y);
              if (x == -1&&y == -1)
                      break;
              if (x == 0&&y == 0)        //只有根结点
                      printf ("Case %d is a tree.\n",count++);

              else
              {
                      b[j++] = x;                      //b数组存储 后面用来查找是否会形成森林
                      b[j++] = y;
                      Union (x,y);
                      while (1)
                      {
                              scanf ("%d%d",&x,&y);
                              if (!x&&!y)
                                      break;
                              b[j++] = x;
                              b[j++] = y;
                              Union (x,y);

                      }
                      for (i = 0;i < j-1;i ++)
                      {
                              if (find(b[i]) != find(b[i+1]))
                              {
                                      flag = 1;
                                      break;
                              }
                      }
                      if (!flag)
                              printf ("Case %d is a tree.\n",count++);
                      else
                              printf ("Case %d is not a tree.\n",count++);
              }
      }
      return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值