【并查集】判断是否为树

本文介绍了如何利用并查集算法来判断一组有向边的集合是否构成一棵树。根据树的特性,如每个节点最多有一个父节点、无环、只有一个根节点等,通过并查集实现数据的合并与环检测,从而确定输入的图是否为树。
部署运行你感兴趣的模型镜像

【问题描述】

树是一种大家都不陌生的数据结构,它有可能是一颗空树或是一些满足要求的节点连接而成的有向边的集合。

一棵树只有一个根节点,根节点没有指向它的边。

除了根节点的每一个节点都只有一条边指向它。

出现环的图都不是树。

对一些节点连接而成的有向边的集合进行判定,判定每一组的输入数据构成的图是否是一棵树。

【输入】

每输入一对都为0的数时,表示一组数据输入完毕。每条边由一对正整数表示,第一个数为有向边的起始点,第二个数为有向边的终止点。一对负数的输入表示输入的结束。

【输出】

每组测试数据输出一行判定结果,若输入的图为树,则输出“Case k is a tree.”,否则输出“Case k is not a tree.”。其中k表示每组数据的编号(编号从1开始)。

【解题报告】

运用并查集可以判定一个图是否为树。

根据树的定义与特点,需考虑的情况有:

(1)树中节点至多只能有一个父节点;

(2)树中不能出现环;

(3)构成的图只能有一个根节点,否则构成的将是森林而不是一棵树。

通过观察输入输出可知,题中编号是随即的,所以在编程中要对出现的点标记才能判断。

Step1:对每对输入的根节点标记表示这些节点出现过,进行并操作。并操作时两个节点不能有相同的根节点否则将构成环;假设b节点要接到a上,则要保证b节点是一个根节点,否则若进行并操作,b将会有两个父节点;若无以上情况,则可以合并两棵树。

Step 2:每组数据输入结束后,要计算整个图中的根节点总数,若根节点总数不为1,则构成的图不是一棵树。

Step 3:根据以上判断就可以输出结果了,每组结果输出后要初始化数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int father[1000000], flag[1000000];

int findset(int x)//查
{
	if(x != father[x])
		father[x]=findset(father[x]);//路径压缩
	return father[x];
}

int unionset(int a, int b)//并
{
	int x=findset(a);
	int y=findset(b);

	if(y != b)//b连接在a上,要保证b是个根节点,否则b将有两个父节点
		return 1;

	if(x == y)//如果a,b在同一棵树中,若再进行并操作就会产生环
		return 1;
	else
		father[y]=x;//若无以上情况,则可以合并两棵树
	return 0;
}

int main()
{
	int a, b, key=0, p=1, i, max=0, t=0;
	for(i=1; i<=999999; i++)
		father[i]=i;

	memset(flag, 0, sizeof(flag));

	while(1)
	{
		scanf("%d%d", &a, &b);
		if(a>max) max=a;
		if(b>max) max=b;
		if(a<=-1 && b<=-1) break;

		if(a==0 && b==0)
		{
			for(i=1; i<=max; i++)
			{
				if(flag[i]==1 && father[i]==i)
					t++;

				if(t>=2) break;
			}

			if(key>0 || t>=2)
				printf("Case %d is not a tree.\n", p++);
			else
				printf("Case %d is a tree.\n", p++);

			for(i=1; i<=999999; i++)
				father[i]=i;

			key=0; t=0; max=0;
			memset(flag, 0, sizeof(flag));
			continue;
		}

		flag[a]=1;flag[b]=1;//对输入的编号标记
		key+=unionset(a,b);//若出现不合法的情况,key的值会大于0
	}

}



 

您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值