hdu1325Is It A Tree?——基础并查集(考思路)

题意:告诉你送一个点到另外一个点的方向,问能不能构成一棵没有循环的树。

大致思路:首先要是一棵树,如果是一棵树的话,那么点的个数应该等于给出的路径的个数-1;

详细过程:首先是用数组把数存下来,

把出现的数用mark数组标记下来,因为可能会出现1,3,4没有2的例子。

然后用非递归的并查集模板找根,然后根据起点到终点的路径连在一起,用num数组记录树上点的个数。

最后就是判断一下树的个数,还有两个“个数”的关系。

注意,数组开到20以上就可以,最好是G++提交。
测试数据,
0 0 // true
1 1 0 0 // false
1 2 2 1 0 0 //false
1 2 2 3 3 4 4 1 0 0 // false
1 2 2 3 3 1 5 6 0 0 // false
2 3 0 0 // true 
代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int start[22];
int end1[22];
int root[22];
int num[22];
int mark[22];
int find_root(int son)
{
while(son!=root[son])
{
root[son]=son;
}
return root[son];
}
int pp=1;
int main()
{
int i;
while(scanf("%d%d",&start[1],&end1[1])!=EOF)
{

if(start[1]<0||end1[1]<0) break;
else if(start[1]==0&&end1[1]==0)    //0 0直接输出,
{
printf("Case %d is a tree.\n",pp);
pp++;
}
for(i=2;;i++)
{
scanf("%d%d",&start[i],&end1[i]);
if(start[i]==0||end1[i]==0) break;
}
int num_number=0,max=0,min=100;//num_number记录有多少个点
memset(mark,0,sizeof(mark));
for(int j=1;j<i;j++)//第i个存的是0 0;
{
if(mark[start[j]]==0)
{
mark[start[j]]=1;
num_number++;
}
if(mark[end1[j]]==0)
{
mark[end1[j]]=1;
num_number++;
}
if(max<start[j]) max=start[j];
if(max<end1[j]) max=end1[j];
if(min>start[j]) min=start[j];
if(min>end1[j]) min=end1[j];
}
for(int j=min;j<=max;j++)
{
if(mark[j]==1)
root[j]=j;num[j]=1;
}
int fstart,fend;
for(int j=1;j<=i-1;j++)//正常的并查集
{
fstart=find_root(start[j]);
fend=find_root(end1[j]);
if(fstart!=fend)
{
root[fend]=fstart;
num[fstart]+=num[fend];
}
}
int qq=0;//写case用
for(int j=min;j<=max;j++)
{
if(num[j]>=num_number)//树上的节点大于等于(为了严谨,理论上可以等于的)记录的节点,则说明构成一棵树
{
if(i==num_number)//并且两个“个数”相等(i-1==num_number-1)
{
printf("Case %d is a tree.\n",pp);
pp++;

qq=1;//记录一下,确实构成一棵树了
break;
}
}
}
if(qq==0)//多于一棵树了,
{
printf("Case %d is not a tree.\n",pp);
pp++;
}
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值