poj1308:Is It A Tree?

题目链接:http://poj.org/problem?id=1308

判断给定的序列是否为能组成树判断条件如下:

1.空树是树

2.树中无环路存在

3除根节点外,每个节点的入度为0

4.只能存在一个根节点

我第二次用并查集写的时候,这题在poj上可以AC却在hduoj上AC不了,各种测试都通过 ,就是不AC,费了很长时间。郁闷!

在两个oj上都能AC的代码如下:

#include<iostream>
#include<string.h>
using namespace std ;
const int MAX = 1000 ;
int pre[MAX] ;
int finds(int  ) ;
int main()
{
	int n , m ;
	int c = 1 ;
	int i , j ;
	bool s ;

	//freopen("data.in" , "r" , stdin) ;

	while(cin>>m>>n,!(n<0&&m<0))
	{
		memset(pre,0,sizeof(pre)) ;
		i = 0 ;
		pre[n] = m ;
		s = true ;
		if(m==0&&n==0)
		{
			cout<<"Case "<<c++<<" is a tree."<<endl;
			continue ;
		}
		while(cin>>m>>n,!(m==0&&n==0))
		{
			if(pre[n]!=0 )
				s = false ;
			else
				pre[n] = m ;
		}
		if(s)
		{
			for( i = 0 ; i< MAX ;i++)
			{
				if(pre[i])
				{
					break ;
				}
			}
			m = finds( i ) ;
			for(i = 0 ; i < MAX ;i++)
			{
				if(pre[i]!=0&&m!=finds(i))
				{
					s = false ;
					break ;
				}
				if(m==0)
				{
					s = false ;
					break ;
				}
			}
		}
		cout<<"Case "<<c++ ;
		if(s) cout<<" is a tree."<<endl;
		else cout<<" is not a tree."<<endl;
	}
	return 0 ;
}
int finds(int key )
{
	int r =key ;
	int flag [MAX] ;
	memset(flag,0,sizeof(flag)) ;

	while(pre[r]!=0&&flag[r]!=1)
	{
		flag[r] = 1 ;

		r = pre[r] ;

	}
	if(pre[r]==0) return r ;
	else  return 0 ;
}

在poj上AC,在hduoj上不AC的代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std ;

const int maxn = 2005 ;

int  parent[maxn]  ;
bool vis[maxn] ;
bool flag  ;

void init()
{
	int i;

	flag = 1 ;

	for(i = 0 ; i < maxn ; i ++)
	{
		parent[i] = i ;
		vis[i] = 0 ;
	}
}

int  Find_x(int x)
{
	int r = x ;

	while(parent[r]!=r)
	{
		r = parent[r] ;
	}

	return r ;
}

void Union(int x , int y)
{
	int p = Find_x(x) ;
	int q = Find_x(y) ;

	if(p==q)
		flag = 0 ;

	else
		parent[q] = p ;
}

bool count()
{
	int i ;
	int sum ;

	sum = 0 ;

	for(i = 0 ; i < maxn ; i ++)
	{
		if(vis[i]&& parent[i]==i)
		{
			sum ++ ;
		}
		if(sum > 1)
			return 0 ;
	}
	return 1 ;
}

int main()
{
	int p ;
	int q ;
	int test ;
	test = 0 ;

	//freopen("data.in" , "r" , stdin) ;

	while(scanf("%d%d" , &p , &q)!=EOF , !(p < 0 && q < 0))
	{
		init() ;

		if(p==0 && q==0)
		{
			printf("Case %d is a tree.\n" , ++test ) ;
			continue ;
		}

		else{

			Union(p , q) ;

			vis[p] = vis[q] = 1 ;

			while(scanf("%d%d" , &p , &q)&&(p||q))
			{
				Union(p ,q) ;

				vis[p] = vis[q] = 1 ;
			}

			if(flag && count())
				printf("Case %d is a tree.\n" , ++test) ;

			else
				printf("Case %d is not a tree.\n" , ++test) ;
		}
	}
	return 0 ;
}

求指出错误的地方

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值