zoukankan      html  css  js  c++  java
  • POJ 1308

    http://poj.org/problem?id=1308

    题意:判断这是不是一棵树。

    思路:这个题还是有部分坑点的。首先空树也是一棵树,还有森林不是树。

    关于森林的判断我是利用并查集把每一个点压缩路径,看一共有几个原始点,超过一个,则不是树是森林。

    关于并查集

    寻找以及压缩的代码

     1 int Find(int x)
     2 {
     3     int _b,int _x=x;
     4     while(belg[_x]!=_x)     //压缩路径,找到它的最顶端的点。
    5 { 6 _x=belg[_x]; 7 } 8 while(belg[x]!=x) //把这一系列的点的父亲节点都更新到最顶端的点。 9 { 10 _b=belg[x]; 11 belg[x]=_x; 12 x=_b; 13 } 14 return _x; 15 }

    关于合并

     1 int Union(int i,int j)
     2 {
     3     if(rand()&1)     //随机分配
     4     {
     5         belg[j]=i;
     6     }
     7     else 
     8     {
     9         belg[i]=j;
    10     }
    11 }
     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <iostream>
     4 #define l 10010
     5 
     6 using namespace std;
     7 
     8 int belg[l];
     9 
    10 int fin(int x)
    11 {
    12     int _b,_x=x;
    13     while(belg[_x]!=_x&&belg[_x])
    14     {
    15         _x=belg[_x];
    16     }
    17     while(belg[x]!=x&&belg[x])
    18     {
    19         _b=belg[x];
    20         belg[x]=_x;
    21         x=_b;
    22     }
    23     return _x;
    24 }
    25 
    26 int main()
    27 {
    28    // freopen("in.txt","r",stdin);
    29     //freopen("out.txt","w",stdout);
    30     int m,n,ans,cas,father;
    31     bool mark[l];
    32     cas=0;
    33     while(scanf("%d%d",&m,&n),m!=-1||n!=-1)
    34     {
    35         ans=1,father=0;
    36         memset(belg,0,sizeof(belg));
    37         memset(mark,false,sizeof(mark));
    38         belg[n]=m;
    39         mark[n]=true;
    40         if(m==n&&m!=0) ans=0;
    41         if(m==n&&m==0) ans=1;
    42         else while(scanf("%d%d",&m,&n),m||n)
    43         {
    44             if(belg[m]==n) {ans=0;continue;}
    45             if(belg[n]) ans=0;
    46             if(n==m) ans=0;
    47             if(!belg[n]&&n!=m) belg[n]=m;
    48             fin(n);
    49             mark[n]=true;
    50         }
    51         for(int i=0;i<100;i++)
    52             if(mark[i]) fin(i);
    53         for(int i=0;i<100;i++)
    54         {
    55                 if(father==0&&mark[i]) {father=belg[i];continue;}
    56                 if(mark[i]&&belg[i]!=father) {
    57                         ans=0;
    58                         break;
    59                 }
    60         }
    61         if(ans) printf("Case %d is a tree.
    ",++cas);
    62         else printf("Case %d is not a tree.
    ",++cas);
    63     }
    64     return 0;
    65 }

    测试数据:

    1 2 2 3 3 1 5 6 0 0
    
    0 0
    
    0 0
    
    1 2 3 4 4 5 5 3 0 0
    
    2 1 3 1 4 1 5 1 0 0
    
    2 1 3 1 4 1 0 0
    
    1 2 4 5 5 4 0 0
    
    1 2 1 3 1 4 1 5 0 0
    
    -1 -1
    

     答案

     Case 1 is not a tree.

     Case 2 is a tree.
     Case 3 is a tree.
     Case 4 is not a tree.
     Case 5 is not a tree.
     Case 6 is not a tree.
     Case 7 is not a tree.
     Case 8 is a tree.

  • 相关阅读:
    CodeForces 19D Points (线段树+set)
    FZU 2105 Digits Count
    HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)
    HDU 5634 Rikka with Phi (线段树)
    Java实现 蓝桥杯 算法提高 转圈游戏(暴力快速幂)
    Java实现 蓝桥杯 算法提高 转圈游戏(暴力快速幂)
    Java实现 蓝桥杯 算法提高 转圈游戏(暴力快速幂)
    Java实现 蓝桥杯 算法提高VIP Substrings(暴力)
    Java实现 蓝桥杯 算法提高VIP Substrings(暴力)
    Java实现 蓝桥杯 算法提高VIP Substrings(暴力)
  • 原文地址:https://www.cnblogs.com/Tree-dream/p/5707380.html
Copyright © 2011-2022 走看看