hdu1325 Is It A Tree?并检查集合

pid=1325">职务地址

试想一下,在词和话题hdu1272是一样的。

可是hdu1272的博文中我也说了。数据比較水,所以我用非并查集的方法就AC了。

可是这题的数据没那么水,要用到并查集来解。这题的盲点和重点有这么几个:

  • 输入不是以-1 -1结束,而是以两个负数结束
  • 须要用并查集来推断是不是仅仅有一个“根”
  • 须要推断全部节点的入度是否大于1
  • 本题输入的格式。也要注意一下。

能够先忽略图中的方向的。由于假设有环的话,就变成图了。若严格的依照用parent数组来保存上一级父节点的方法,会有冲突。

比方这个图中,8的父节点有两个那么parent[8]应该怎样存储呢??所以我们能够把它看成无向图,无所谓父子。仅仅需把关系集合merge合并就好了。这样的有多个父节点的情况,就使用一个记录入度的数组来标记就好了。

#include<iostream>
using namespace std;
const int MAX=1000;
int rudu[MAX+10];//入度
int parent[MAX+10];
int root[MAX+10];//保存是否为根
bool flag = true;
int r=0;
int getParent(int a)
{
	int k=parent[a];
	if(parent[a]!=a)
	{
		parent[a]=getParent(parent[a]);
	}
	return parent[a];
}
void merge(int a,int b)
{
	int p1=getParent(a);
	int p2=getParent(b);
	if(p1==p2)
		return;
	parent[p1]=p2;
	root[p2]=1;
	root[p1]=0;
}
void init()
{
	r=0;
	flag = true;
	for(int i=0;i<=MAX;i++)
	{
		parent[i]=i;
		rudu[i]=0;
		root[i]=0;
	}
}

void main()
{
	int a,b,c=1;

	init();
	while(cin>>a>>b,a>=0&&b>=0)
	{
		if(!a&&!b)
		{
			for(int i=0;i<=MAX;i++)
			{
				if(rudu[i]>1)
					flag = false;
				if(root[i])
					r++;
			}
			if(r>1)
				flag=false;
			if(flag)
				cout<<"Case "<<c++<<" is a tree."<<endl;
			else
				cout<<"Case "<<c++<<" is not a tree."<<endl;
			init();
			continue;
		}
		if(getParent(a)!=getParent(b))
			merge(a,b);
		rudu[b]++;
	}
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-12-19 16:14:12

hdu1325 Is It A Tree?并检查集合的相关文章

HDU1325 Is It A Tree? 并查集

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1325 这题与HDU1272 小希的迷宫 (并查集) 非常像,不过细细看,还是有一点区别的.就是这题的路径是单向的,每次只能由起点指向终点,在连接之前终点必须是根节点. 注意的问题: 1.不能成环,即每次输入的两个数的根节点不能相同: 2.最终根节点数目为一 3.注意当只输入"0 0" 时要输出"Case %d is a tree." 4.路径是单向的,即每次只能由起点指

Reflection和Expression Tree解析泛型集合快速定制特殊格式的Json

很多项目都会用到Json,而且大部分的Json都是格式固定,功能强大,转换简单等,标准的key,value集合字符串:直接JsonConvert.SerializeObject(List<T>)就可以搞定了,但凡事并非千篇一律,比如有的时候我们需要的Json可能只需要value,不需要key,并且前后可能还需要辅助信息等等,那该怎么办呢?我所能想到的可能有两种方案,1.自定义跟所需json格式一样的数据结构model,然后用JsonConvert.SerializeObject(model)直

URAL - 1966 - Cycling Roads(并检查集合 + 判刑线相交)

意甲冠军:n 积分,m 边缘(1 ≤ m < n ≤ 200),问:是否所有的点连接(两个边相交.该 4 点连接). 主题链接:http://acm.timus.ru/problem.aspx?space=1&num=1966 -->>对于每条边,边上的两端点并入集合,枚举边与边.推断他们是否相交,是的话各点并入集合,最后看集合内元素的个数是否为n.. #include <cstdio> #include <cmath> const int MAXN =

hdu1325 Is It A Tree?(二叉树的判断)

Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17520    Accepted Submission(s): 3939 Problem Description A tree is a well-known data structure that is either empty (null, void, n

NYOJ129 决策树 【并检查集合】

树的判定 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 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 ex

HDU1325 Is It A Tree? 【并查集】

Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14197    Accepted Submission(s): 3170 Problem Description A tree is a well-known data structure that is either empty (null, void, n

《算法导论》2.3-7 检查集合中是否存在两数字和为指定的X--算法和证明

习题2.3-7:设计一个算法,对于一个给定的包含n个整数的集合S和另一个给定的整数X,该算法可以在时间内确定S中是否存在两个元素,使得它们的和恰为X. 解题思路:首先应该想到的是先用一个的排序算法对S中的元素进行排序.接下来有两种处理思路,第一种思路是遍历已经排好序了的S中的所有元素a,并采用 二分查找的方法在S中查找X-a,如果能够找到,那么说明S中确实存在两个元素的和为X,算法终止.这种思路很显然是满足的限制要求的:第二种思路是我自己 想出的一个算法,这个算法也很简单,但是其正确性不是很好证

普林斯顿大学公开课 算法1-10:并检查集合-高速整合方法优化

本节介绍了高速综合优化算法. 重量的概念,每次操作的时候将重量小的部件挂在重量大的部件之下. 这样就避免了树形结构太高的问题. 下图展示了优化前后的树形结构深度的对照. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FpcGVpY2hhbzI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 证明 能够证明每一个节点的深度最大为lgN. 由于

poj 2513 Colored Sticks(欧拉路径+并检查集合+特里)

题目链接:poj 2513 Colored Sticks 题目大意:有N个木棍,每根木棍两端被涂上颜色.如今给定每一个木棍两端的颜色.不同木棍之间拼接须要颜色同样的 端才干够.问最后是否能将N个木棍拼接在一起. 解题思路:欧拉通路+并查集+字典树. 欧拉通路,每一个节点的统计度,度为奇数的点不能超过2个.并查集,推断节点 是否全然联通. 字典树,映射颜色. #include <cstdio> #include <cstring> #include <string> #i