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.\n",++cas);
62         else printf("Case %d is not a tree.\n",++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.

posted @ 2016-07-26 14:36  一个_小菜鸟  阅读(280)  评论(0编辑  收藏  举报