zoukankan      html  css  js  c++  java
  • POJ 1308(并查集) (Data_Structure)

            满足一下条件是树:

     (1)只有一个根;

     (2)一个入度为0的节点,其他节点入度都为1

       

    第一个用并查集,第二个搞个数组统计下就OK。

    我用set来存点,因为这些点在输入中可能出现多次,用set只会存一次,set方便些啦!

    代码:

    #include <cstdio>
    #include <cstdlib>
    #include <set>
    #include <iterator>
    #define N 10001
    using namespace std;
                      
    set<int> s;
    set<int>::iterator iter;
    
    int father[N];
    int degree[N];
    
    void make_set();
    int find_set(int x);
    void unin(int x,int y);
    
    int main()
    {
       int i,j,f,a,b,k,zero;
       bool fail;
       
         k = 1 ;
         while(scanf("%d%d",&a,&b) && (a!= -1 && b != -1))
         {
              /*
                空树也是树 
              */
              if( a == 0 && b == 0)
              {
                printf("Case %d is a tree.\n",k++); 
                continue;   
              }
              /*
                每组数据都得清空 set容器 
              */
              s.clear();
              
              s.insert(a);
              s.insert(b);       
              /*
                初始化 
              */   
              make_set();           
              unin(a,b);
              
              ++degree[b];
              
              while(scanf("%d%d",&a,&b) && (a&&b))
              {
                 s.insert(a);
                 s.insert(b);
                 unin(a,b);
                 ++degree[b];                                                
              }
            
              f = find_set(father[*s.begin()]);
              zero = 0 ;//统计有几个入度为 0 的点 
              fail = false;
              
              for( iter = s.begin(); iter != s.end(); ++iter)
              {
                 /*
                   树的每个点的祖先都一样,否则不是树 
                 */
                  if(f != find_set(father[*iter]))
                  {
                       fail = true;
                       break; 
                  }      
                 /*
                   树不能有入度大于 1的节点,否则不是树 
                 */
                  if(degree[*iter]>1) 
                  {
                       fail = true;
                       break;                    
                  }
                  else
                  {
                      /*
                       统计根 
                      */
                      if(degree[*iter] == 0)
                      ++zero;    
                  }
                  
              }
              
              printf("Case %d ",k++);
              if(fail || zero != 1)
              {
                    printf("is not a tree.\n");  
              }
              else
              printf("is a tree.\n");
         }
       return 0;
    }
     
    void make_set()
    {
       int i;
       for(i= 1; i < N; ++i)
       {
          father[i] = i;
          degree[i] = 0;       
       }     
    }
    
    int find_set(int x)
    {
        int t;
        if(x != father[x])
        father[x] = find_set(father[x]);//路径压缩 
        return father[x];
    }
    /*
      因为是树,合并是有方向的 
    */
    void unin(int x,int y)
    {
       x = find_set(x);
       y = find_set(y);
       father[y] = x;
    }
            
    

      

           

  • 相关阅读:
    python面向对象--元类
    python面向对象--类的装饰器
    python--异常处理
    python面向对象--类的内置函数
    python面向对象--类的内置方法
    关于discuz论坛邮箱配置
    python面向对象--item方法
    python面向对象--包装标准类型及组合方式授权
    python面向对象--反射机制
    python面向对象的三大特征--封装
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2442979.html
Copyright © 2011-2022 走看看