bhu1272小希的迷宫

题意不说了,是中文。

思路就是并查集,也不用说了。

难点1、判断条件:两个数不能有相同的根;还有就是有且只有一个根。

难点2、当直接输入0,0,时输出Yes。

WA过好多遍,之后重新整理思路,重写一遍就A了,如果细节上没处理好一直WA,不妨试试重写,这是忠告,适合每道题。



我的测试数据::


1 2 1 3 1 5 1 4 3 6 2 7 4 8 5 9 3 5 0 0


1 2 1 3 1 5 1 4 3 6 2 7 4 8 5 9 0 0


6 8  5 3  5 2  6 4  5 6  0 0


8 1  7 3  6 2  8 9  7 5  7 4  7 8  7 6  0 0


6 8  5 3  5 2  6 4  5 6  3 8  0 0


1 2 2 1 0 0 


1 2 1 3 4 5 4 6 0 0


1 2 2 3 3 4 1 4 5 6 6 7 7 8 5 8 0 0


-1 -1



A的代码:::

#include<stdio.h>
#include<string.h>
#define max 100010
int father[max];
int mark[max],num[max];
int maxnum,minnum;
int n[max],m[max];
void init()
{
int k;
for(k=minnum;k<=maxnum;k++)
{
father[k]=k;num[k]=1;
}
}
int find(int son)
{
if(father[son]!=son)
{
father[son]=find(father[son]);
}
return father[son];
}
int main()
{
int i,j,fn,fm,cir;
while(scanf("%d%d",&n[0],&m[0])!=EOF)
{
maxnum=0;minnum=max;memset(mark,0,sizeof(mark));

if(n[0]==-1&&m[0]==-1) break;
else if(n[0]==0&&m[0]==0)
{
printf("Yes\n");
continue;
}
mark[n[0]]=1;mark[m[0]]=1;
i=1;
while(scanf("%d%d",&n[i],&m[i]))
{
if(n[i]==0&&m[i]==0) break;
mark[n[i]]=1;mark[m[i]]=1;
i++;
}  //输入 



for(j=0;j<i;j++)
{
if(maxnum<n[j]) maxnum=n[j];
if(minnum>n[j]) minnum=n[j];
if(maxnum<m[j]) maxnum=m[j];
if(minnum>m[j]) minnum=m[j];
}//最大和最小 

init();cir=0;//初始化 

for(j=0;j<i;j++)
{
fn=find(n[j]);
fm=find(m[j]);
if(fn==fm)
{
cir=1;break;
}
if(num[fn]==num[fm])   //A掉之后考虑过如果不用num计数会怎么样,结果是爆栈,只是我的方法适合这样吧。 
{
if(fn>fm)
{
num[fn]+=num[fm];father[fm]=fn;
}
else
{
num[fm]+=num[fn];father[fn]=fm;
}
}
else
{
if(num[fn]>num[fm])
{
num[fn]+=num[fm];father[fm]=fn;
}
else
{
num[fm]+=num[fn];father[fn]=fm;
}
}
}//找祖宗合并 
if(cir==1)  //看是否成环,如果成环,cir==1 
{
printf("No\n");
continue;
}
for(i=minnum;i<=maxnum;i++)//判断几棵树 
{
if(i==father[i]&&mark[i]==1) {cir++;}//为了少定义变量,所以还用cir,因为如果没成环,cir还是等于0的, 
}
if(cir==1) printf("Yes\n");//只有一棵树就对了 
else printf("No\n");
}
return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值