Is It A Tree?

Is It A Tree?

时间限制: 1秒  内存限制: 10240KB

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 between 1 and 1000.

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.

Source

North Central North America 1997

先前看到一些大神blog说是用并查集来解决的,我不会用只能另行他法,看到了用性质:结点个数 = 边的个数 + 1 来解决的方法;于是试上一试,果然拍死了bit,和poj上的,但是hdu上的就悲了个剧了wa了。看了里面的讨论发现那题,果然有问题,发火,居然一个连给出的样例都过不了的代码居然就把这道题给A了。抓狂


#include<stdio.h>

int node_counter;//节点的个数
int edge_counter;//边的个数
int i;

void insert(int c,int d,int *nodes){	

	int add_one_node= 1,add_two_node = 1;
	for( i = 0; i < node_counter; ++i)
	{
		if(nodes[i] == c){
			add_one_node = 0;
		}
		if(nodes[i] == d){
			add_two_node = 0;
		}
	}
	if(add_one_node){
		nodes[node_counter ++] = c;
	}
	if(add_two_node){
		if(nodes[node_counter - 1] != d){
			//加此判断防止出现 1 1 这种自己指向自己的数据;
			nodes[node_counter ++] = d;
		}
	}
	++edge_counter;
	return ;
}

int main(){
	//利用性质:结点个数 = 边的个数 + 1 来解决;
	int a,b;            //输入的成对数据
	int test_case =  0; //判断的树个数
	int nodes[1100];    //树的接点个数
	//FILE *fp;
	//fp = freopen("in.txt","r",stdin);

	while(scanf("%d%d",&a,&b),~a||~b){
		node_counter = 0;
		edge_counter = 0;
		++test_case;
		while(a||b){
			insert(a,b,nodes);
			scanf("%d%d",&a,&b);
			
		}
		//因空树也是一棵树
		if(!node_counter){
			++node_counter;
			//edge_counter += 1;
		}
		if(node_counter == edge_counter + 1){
			printf("Case %d is a tree.\n",test_case);
		}else{
			printf("Case %d is not a tree.\n",test_case);
		}
	}
//	fclose(fp);
	return 0;
}
poj 上大神给的几组测试用例

1: 0 0 空树是一棵树
2: 1 1 0 0 不是树 不能自己指向自己
3: 1 2 1 2 0 0 不是树....自己开始一直在这么WA  好郁闷 重复都不行呀~~5555
4: 1 2 2 3 4 5 0 0不是树  森林不算是树(主要是注意自己)
5: 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1 0  0  注意 一个节点在指向自己的父亲或祖先 都是错误的 即 9-->1 错
6: 1 2 2 1 0 0 也是错误的

hdu上的一个参考,连给的案例都过不了却能AC这道题 难过

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
//  判定树是否合法 有几条规律可循:
//  判定是否有循环出现 ;
//  判定是否有多个根结点。
//  本来想用 顶点数与连线的差为一的关系来判定
//  上述的第 2 点要求是否合法,
//  但是题中的编号毫无规律可言,便使得统计的难度变大
//  于是开辟了root 数组,专门来统计根的个数
int set[1001],root[1001];

int x,y,cnt=1,flag=0,max=0x7fffffff+1,min=0x7fffffff;

int find(int x)
{
    return set[x]= set[x]==x? x : find(set[x]); //压缩路径,使得各节点均直接指向Root
}

void merge(int x,int y)
{
    root[find(x)]=1;  // 无条件定根
    root[y]=0;        // 无条件回根
    set[y]=find(x);
}

void init()
{
    for(int i=0;i<=1000;++i)
        set[i]=i;
    flag=0,max=0x7fffffff+1,min=0x7fffffff;
    memset(root,0,sizeof(root));
}

int main()
{
    init();
    while(scanf("%d%d",&x,&y),x>=0||y>=0)
    {
        if(x==0&&y==0)
        {
            int r=0;
            for(int i=min;i<=max;++i)
                if(root[i])
                    r++;
            //首先判定根的个数
            if(!flag&&r==1)  //其中 flag 变量表明是否成环
                printf("Case %d is a tree.\n",cnt++);
            else
                printf("Case %d is not a tree.\n",cnt++);
            init();
            continue;
        }   //  输出结果操作
        else
        {
            if(find(x)==find(y))
                flag=1;  // 判定是否成环
            else
                merge(x,y);
            min= min <( x<y? x:y ) ? min : (x<y ? x:y);
            max = max > (x>y ? x: y) ? max :(x>y ? x: y);
        }  // 数据处理操作
    }
    return 0;
}
这是从沐阳的博客中找的代码,给的案例都过不了却能AC!!!
http://www.cnblogs.com/Lyush/archive/2011/05/11/2043731.html




你可能感兴趣的:(Is It A Tree?)