码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1308 Is It A Tree?

时间:2020-02-10 22:18:58      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:memset   连接   alt   splay   can   str   title   http   node   

A - Is It A Tree?  POJ - 1308

题意:输入一组有向边,判断是否能形成一棵树

考察点:连通图和树的定义

森林:多个树的集合

本题要点:
          
          (1)判环,若已存在两点在同一个集合中,此时连接两点会形成环 
          (2)判联通   很坑!!!  如果有多个集合说明不联通
           特判:空树也是树(即没有任何节点)
           只有一个节点,如本题输入的含义会形成自环,即自己指向自己 ,但是树的根节点入度只能为0 

技术图片
  1 #include<iostream>
  2 #include <algorithm>
  3 #include <queue>
  4 #include<cstring>
  5 #include<stdio.h>
  6 using namespace std;
  7 //有几个集合就有几张桌子 
  8 
  9 struct node{
 10     int father;
 11     
 12 }star[300005];
 13 int Find(int x){//查询 
 14     //return x==father[x]? x : Find(father[x]);
 15     
 16     //路径压缩,直接与祖宗节点相连,加快查询速度 
 17     if(x==star[x].father)return x;
 18     star[x].father=Find(star[x].father); 
 19     return star[x].father;
 20 }
 21 const int maxn=1e5+10;
 22 int vis[maxn];
 23 int main() 
 24 {    
 25     //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 26     
 27        int cnt=1;
 28        int a,b;
 29        
 30        while(~scanf("%d%d",&a,&b)&&(a!=-1&&b!=-1)){
 31            
 32            
 33            memset(vis,0,sizeof(vis));
 34            
 35            if(a==0&&b==0){//空树也是树 
 36                printf("Case %d is a tree.\n",cnt++);
 37                continue;
 38            }    
 39            if(a==1&&b==1){
 40                scanf("%d%d",&a,&b);
 41                if(a==0&&b==0)
 42                printf("Case %d is not a tree.\n",cnt++);
 43                continue;
 44            }
 45            /*        并查集初始化           */
 46            for(int i=1;i<=maxn;i++){
 47             star[i].father=i;
 48         }
 49         
 50         vis[a]=vis[b]=1; 
 51         star[a].father=b;
 52         
 53            int flag=0;
 54            while(~scanf("%d%d",&a,&b)&&(a!=0&&b!=0)){
 55                
 56                int fa=Find(a);
 57                int fb=Find(b);
 58                vis[a]=vis[b]=1;
 59                
 60                //同一集合内连线会成环 
 61                if(fa==fb)flag=1;
 62                else{
 63                    
 64                    star[fa].father=fb;
 65                }
 66                
 67               }
 68               
 69               
 70               /*---------输出----------*/
 71               if(flag){//有环直接输出错误 
 72                       printf("Case %d is not a tree.\n",cnt++);
 73               }
 74               else{
 75                   
 76                      int is_one=0;//判断是否只有一个集合 
 77               
 78                   for(int i=1;i<=maxn-1;++i){
 79                           if(vis[i]){//先看看此点是否存在 
 80                               if(i==star[i].father){
 81                                   //若有多个集合
 82                      
 83                                   is_one++;
 84                                } 
 85                            }
 86                         }
 87                         if(is_one==1)printf("Case %d is a tree.\n",cnt++);
 88                         else printf("Case %d is not a tree.\n",cnt++);
 89                   }
 90              
 91             //if(!flag)
 92            
 93           }
 94     /*本题要点
 95           
 96           (1)判环,若已存在两点在同一个集合中,此时连接两点会形成环 
 97           (2)判联通 
 98            特判:空树也是树
 99            只有一个节点,如本题输入的含义会形成自环,即自己指向自己
100            但是树的根节点入度为0 
101     */ 
102     return 0;
103 }
View Code

 

POJ 1308 Is It A Tree?

标签:memset   连接   alt   splay   can   str   title   http   node   

原文地址:https://www.cnblogs.com/simaomao/p/12293046.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!