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;
    }
            
    

      

           

  • 相关阅读:
    C++中整型变量的存储大小和范围
    A1038 Recover the Smallest Number (30 分)
    A1067 Sort with Swap(0, i) (25 分)
    A1037 Magic Coupon (25 分)
    A1033 To Fill or Not to Fill (25 分)
    A1070 Mooncake (25 分)
    js 获取控件
    C#代码对SQL数据库添加表或者视图
    JS 动态操作表格
    jQuery取得下拉框选择的文本与值
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2442979.html
Copyright © 2011-2022 走看看