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.

  • 相关阅读:
    Solr的核心操作案例
    分布式锁
    AngularJS——AngularJS实现地址栏取值
    【转】保证消息队列的高可用性
    【转】Spring线程及线程池的使用
    微信支付实现
    分布式id的生成方式——雪花算法
    重载new和delete
    C++工程实践
    语言基础(27):异常处理
  • 原文地址:https://www.cnblogs.com/Tree-dream/p/5707380.html
Copyright © 2011-2022 走看看