POJ 1308 Is It A Tree?--题解报告

Is It A Tree?

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 31092   Accepted: 10549

Description

A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties.

There is exactly one node, called the root, to which no directed edges point. 
Every node except the root has exactly one edge pointing to it. 
There is a unique sequence of directed edges from the root to each node. 
For example, consider the illustrations below, in which nodes are represented by circles and edges are represented by lines with arrowheads. The first two of these are trees, but the last is not. 

In this problem you will be given several descriptions of collections of nodes connected by directed edges. For each of these you are to determine if the collection satisfies the definition of a tree or not.

Input

The input will consist of a sequence of descriptions (test cases) followed by a pair of negative integers. Each test case will consist of a sequence of edge descriptions followed by a pair of zeroes Each edge description will consist of a pair of integers; the first integer identifies the node from which the edge begins, and the second integer identifies the node to which the edge is directed. Node numbers will always be greater than zero.

Output

For each test case display the line "Case k is a tree." or the line "Case k is not a tree.", where k corresponds to the test case number (they are sequentially numbered starting with 1).

Sample Input

6 8  5 3  5 2  6 4
5 6  0 0

8 1  7 3  6 2  8 9  7 5
7 4  7 8  7 6  0 0

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

Sample Output

Case 1 is a tree.
Case 2 is a tree.
Case 3 is not a tree.

方法一:运用并查集,将有连接关系的点放入同一集合内,判断是否出现环和多个根。如果没有则为树。具体见代码:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstring>
 6 using namespace std;
 7 struct edge
 8 {
 9     int s,t;
10 }E[1000];
11 int par[1000],Rank[1000];
12 int k=0,n=0,ne=0,num=0;
13 bool used[2000];//used用于记录1到出现的最大数字之间的数字是否使用过
14 void init(){
15     memset(Rank,0,sizeof(Rank));
16     for(int i=1;i<=1000;i++)
17         par[i]=i;
18 }
19
20 int Find(int i){
21     if(par[i]==i)return i;
22     else return Find(par[i]);
23 }
24 bool same(int x,int y){
25     return Find(x)==Find(y);
26 }
27
28 void unite(int x,int y){
29     if(same(x,y))return;
30     else{
31         x=Find(x);
32         y=Find(y);
33         if(Rank[x]<Rank[y])
34             par[x]=y;
35         else{
36             par[y]=x;
37             if(Rank[x]==Rank[y]) Rank[x]++;
38         }
39     }
40 }
41 void tree(){
42     init();
43     bool flag=true;
44     int now=-1;
45     for(int i=1;i<=n;i++){
46         if(!same(E[i].s,E[i].t)){//判断是否首尾相连成环
47             unite(E[i].s,E[i].t);
48         }
49         else{
50             flag=false;
51             break;
52         }
53     }
54
55     for(int i=1;i<=ne;i++){
56         if(used[i]==true&&par[i]==i){//判断根的数目,如果多于1则不是树
57             num++;
58             if(num==2){
59                 flag=false;
60                 break;
61             }
62         }
63     }
64     if(flag)printf("Case %d is a tree.\n",++k);
65     else printf("Case %d is not a tree.\n",++k);
66 }
67
68 int main(){
69     int x,y;
70     while(scanf("%d%d",&x,&y)){
71         if(x==-1&&y==-1) break;
72         else if(x!=0&&y!=0){
73             ++n;
74             E[n].s=y;
75             E[n].t=x;
76             ne=max(x,max(ne,y));
77             used[x]=true;//因为题目没有给出数目采用这种方法判断需要的循环次数
78             used[y]=true;
79         }
80         else{
81             tree();
82             memset(used,0,sizeof(used));
83             init();
84             n=0;
85             ne=0;
86             num=0;
87         }
88     }
89     return 0;
90 }
方法二:利用树的性质:(1)点数=边数+1,这个性质可以去掉多根的情况。(2)一个点最多有一个父节点,这个性质可以去掉成环的情况,具体代码如下:
 1 #include<cstdio>
 2 #include<cstring>
 3
 4 using namespace std;
 5
 6 int x,y,a[1000]={0},m,n,flag;
 7 int main()
 8 {
 9     int k=1;
10     while(scanf("%d%d",&x,&y))
11     {
12         if(x==-1&&y==-1) break;
13         m++;//输入一组边数+1
14         if(a[y]==2){flag=1;}//如果y已经作为过子节点,再一次做子节点,说明出现两个父节点(也可能是重复的边,也不是树),不是树
15         if(!a[x]&&x){a[x]=1;n++;}//1为父节点,2为子节点标记个点,点数+1
16         if(!a[y]&&y){a[y]=2;n++;}
17         if(x==0&&y==0)
18         {
19             if(!flag&&((n==m)||(n==0&&m==1))) printf("Case %d is a tree.\n",k++);//由于0 0也算入边内,因此m为边数+1,m==n;需特判空树
20             else printf("Case %d is not a tree.\n",k++);
21             m=0,n=0,flag=0;
22             memset(a,0,sizeof(a));
23         }
24     }
25     return 0;
26 }
以上两种方法均可,代码都能AC,如有问题,还请指出,不胜感激。
时间: 2024-10-13 10:30:26

POJ 1308 Is It A Tree?--题解报告的相关文章

HDU 1325 POJ 1308 Is It A Tree? (并查集)

这道题就是裸并查集,关键在于对不是树几种的判断 1. 空树是树 2. 森林不是树 3. 无环 或者从入度来看:1,无环:2,除了根,所有的入度为1,根入度为0:3,这个结构只有一个根,不然是森林了. 这道题本来暑假做的POJ 1308 但是HDU没有过.在于空树没有考虑. 用并查集判断有多少个森林注意编号是随机的,不是次序.... /* input: 0 0 1 1 0 0 1 2 1 2 0 0 1 2 2 3 4 5 0 0 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9

HDU 1325,POJ 1308 Is It A Tree

HDU认为1>2,3>2不是树,POJ认为是,而Virtual Judge上引用的是POJ数据这就是唯一的区别....(因为这个瞎折腾了半天) 此题因为是为了熟悉并查集而刷,其实想了下其实好好利用sort应该能更简单A掉,下次有空再去试试... 题目大意:判断是否为树,so: 1,无环: 2,除了根,所有的入度为1,根入度为0: 3,这个结构只有一个根,不然是森林了:4.空树也是树,即第一次输入的两个数字为0 0则是树,其他时候输入只是结束条件 因为POJ和HDU题面一样,要求不一样,所以这题

POJ 1308 Is It A Tree? &amp;&amp; NYOJ 129 (树的判定+并查集)

[题目链接]click here~~ [题目大意]给定多对节点,判断所有节点能否组成一棵树 [解题思路]并查集的基本操作,定义node,edge,统计node和edge的数目,如果(edge==node-1||node==0)则可以成树 树的判定:n个节点,最多n-1条环,只有一个入度为边,不成0 的点,其他入度不大于1,不过要注意poj数据里如果1 1 0 0也会不符合要求,也就是不能自己指向自己 代码: /* Author:HRW 树的判定: n个节点,最多n-1条边 不成环 只有一个入度为

POJ 1308 Is It A Tree?

Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24299   Accepted: 8339 Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edge

POJ 1308 Is It A Tree? (并查集)

Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23006   Accepted: 7898 Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edge

[POJ 1308]Is It A Tree?(并查集判断图是否为一棵有根树)

Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the root, t

POJ 1308 Is It A Tree? (并查集)

Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24237   Accepted: 8311 Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edge

POJ - 1308 Is It A Tree?【并查集】

A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the root, to which no d

POJ 2499 Binary Tree 题解

本题使用所谓的辗转相除法. 还需要逆过来遍历二叉树.可以想象给出的数据点是根节点,然后遍历到根节点(1,1). 考的是根据给出的规则,总结规律的能力. #include <stdio.h> namespace BinaryTree2499_1 { int main() { int T, a, b, le, ri; scanf("%d", &T); for (int t = 1; t <= T; t++) { scanf("%d %d", &