hdu1325Is It A Tree?【并差集】

#include <iostream>
using namespace std;


//题意:和题目1272类似,判断给定的有向图是不是一颗树
//思路:树的定义:或着是一颗空树,或者为一颗非空树,只有一个根节点,其他的节点构成了m(m > 0)个
//         互不相交的有限集合,每一个集合本身又是一颗树
//判断方法:1、或者为一颗空树
//          2、对于一颗非空树,只有一个根节点,该节点的入度为0,其他的每一个定点的入度为1
//          3、并且不能有环,即n个节点只能有n-1条边


#define NSIZ 100010
int parent[NSIZ];
int myrank[NSIZ];
int flag[NSIZ];
int degree[NSIZ];

void make_set(int n)
{
	int i;
	memset(flag, 0, sizeof(flag));
	memset(degree, 0, sizeof(degree));
	for(i = 1;i < n; ++i)
	{
		parent[i] = i;
		myrank[i] = 1;
	}
}

int find_set(int x)
{
	if(x != parent[x])
	{
		parent[x] = find_set(parent[x]);
	}


	return parent[x];
}

void union_set(int x, int y)
{
	x = find_set(x), y = find_set(y);
	if(x != y)
	{
		if(myrank[x] < myrank[y])
		{
			parent[x] = y;
			myrank[y] += myrank[x];
		}
		else
		{
			parent[y] = x;
			myrank[x] += myrank[y];
		}
	}
}

int main()
{  
	int n, m;
	int i, t = 1, x, y, fx, fy;
	int minD,maxD;
	int isOK;


	while(scanf("%d %d", &x, &y) != EOF && x > 0 && y > 0)
	{
		if(!x && !y)
		{
			printf("Case %d is a tree.\n", t++);
			continue;
		}

		//init
		make_set(NSIZ);
		isOK = 0;
		minD = min(x, y);
		maxD = max(x, y);

		do
		{
			minD = min(minD, min(x, y));
			maxD = max(maxD, max(x, y));
			flag[x] = 1;
			flag[y] = 1;


			fx = find_set(x);
			fy = find_set(y);
			degree[y]++;


			if(fx == fy)
			{
				isOK = -1; //标志图中有环
			}
			else
			{
				if(degree[y] > 1) //非根节点入度必须为1
				{
					isOK = -1;
				}
				union_set(x, y);
			}

		}while(scanf("%d %d", &x, &y) != EOF && (x + y));


		//图中无环时,看看图是否是连同的,如果不是连同的则会有至少2个根节点
		if(!isOK)
		{
			for(i = minD; i <= maxD; ++i)
			{
				if(flag[i] && i == find_set(i))
				{
					isOK++;
				}
			}
		}

		if(isOK == 1)
		{
			printf("Case %d is a tree.\n", t++);
		}
		else
		{
			printf("Case %d is not a tree.\n", t++);
		}

	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值