杭电 1272 poj 1308 小希的迷宫-程序员宅基地

技术标签: java  

这道题是我学了并查集过后做的第三个题,教我们的学姐说这是并查集的基础题,所以有必要牢牢掌握。

下面就我做这道题的经验,给大家一些建议吧!当然,我的建议不是最好的,还请各位大神指出我的错误来,我也好改正。

1.题目概览

这道题是杭电1272,POJ 1308如果写好了代码可以试一试。

小希的迷宫

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 28572    Accepted Submission(s): 8818

Problem Description

上 次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房 间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走 了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从 5到达8。 

Input

输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。 
整个文件以两个-1结尾。

Output

对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。

Sample Input

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

3 8  6 8  6 4

5 3  5 6  5 2  0 0

-1 -1

Sample Output

YesYesNo

2.题目理解

题目的意思应该不难理解,就是给你很多成对的数,代表有关系的房间的编号,其实就是一棵树的抽象,你可以把这个想成一颗树。

然后,你想一下,形成树的条件。

1.有一个根(root),并且这个根没有入度(没有老爸)。

2.不能形成环。

3.N个结点(node)形成一棵树,有n-1条边。

然后与题目一相比,不就是要你判断给的一组测试数据是不是一棵树。(有坑点,这棵树的结点连通是双向的)

3.分析目标

1.输入输出实现

这题的输入有那么一点特殊,首先题目是以两个-1结束。并且每组测试数据是以两个0结束。

输出很简单,能则输出Yes,否则输出No。

2.实现代码

int a, b;  // 定义接收数据变量

while (~scanf("%d%d", &a, &b) &&!(a<0&&b<0))

{

int flag=1;

if (a==b)

{

if (a) flag=0;   //这是一个坑点,我被坑了好多次。0 0是树,而相同的如1 1不是树

}

else

{

int k=1, max=0;

while (a||b) //循环输入数据 并保存到 mark数组里

{

mark[k][0]=a;

mark[k++][1]=b;

if (max<a) max=a;

if (max<b) max=b;

scanf("%d%d", &a, &b);

}

_make(max);         //  初始化函数 , 使每个节点都指向它自己

for (int i=1; i<k; i++)

if (_union(mark[i][0],mark[i][1])) //合并函数, 使两个节点合并

{

flag=0;

break;

}

if (flag)  //  下面的是  check看是不是一颗树 不然就成深林了

{

int forefather=_find(mark[1][0]);

for (int i=1; i<k; i++)

if (_find(mark[i][0])!=forefather||_find(mark[i][1])!=forefather)

{

flag=0;

break ;

}

}

}

printf("%s\n", flag?"Yes":"No"); //样例输出

3.函数介绍

void _make(int max) 这个函数是初始化函数,目的是让每一个节点都指向他自己。这个函数有一个形参max他其实是一个小优化。一般情况都是从1初始化到100000,时间复杂度是O(n),但是你其实只需要初始化到最大的输入数据就行了,后面的是没必要的。

int _find(int x)这个函数是查找函数,目的是找到祖先。本来这个函数可以压缩路径的。但是我在抗电上测试了一下,压缩路径过后反而时间变多了,适得其反所以还是不压缩路径了。对了此函数的返回值是祖先。如果自己不是自己的祖先的话,此函数会一直递归下去,所以有时候要考虑会不会爆栈。

int _union(int a, int b) 这个函数是合并函数,目的是把两个节点链接起来。 有两个形参,相信读者一看就知道这两个形参的意义了吧。这个函数是最主要的,用它来调用_find()函数,完成合并工作,同时判断有没有环的形成。

4.最后就是这题的坑点分析了

此题的坑点说不多也多,不小心就掉坑里了。

1.就是那个0 0, 1 1之类的特叛,姿势不对就可能,掉进这个坑里。

2.爆栈,这个是不注意,代码写挫了就会爆栈。对了别压缩路径。

3.判断有没有环的形成。

4.判断有没有形成深林。

我就找到这么多了。。。

4.全部代码

#include <stdio.h>

#define MAX 100001

int father[MAX], mark[MAX][2];

void _make(int max)

{

for (int i=1; i<=max; i++)

father[i]=i;

return ;

}

int _find(int x)

{

if (x!=father[x])

x=_find(father[x]);

return x;

}

int _union(int a, int b)

{

a=_find(a);

b=_find(b);

if (a==b) return 1;

father[a]=b;

return 0;

}

int main()

{

int a, b;  // 定义接收数据变量

while (~scanf("%d%d", &a, &b) &&!(a<0&&b<0))

{

int flag=1;

if (a==b)

{

if (a) flag=0;   //这是一个坑点,我被坑了好多次。0 0是树,而相同的如1 1不是树

}

else

{

int k=1, max=0;

while (a||b) //循环输入数据 并保存到 mark数组里

{

mark[k][0]=a;

mark[k++][1]=b;

if (max<a) max=a;

if (max<b) max=b;

scanf("%d%d", &a, &b);

}

_make(max);        //  初始化函数 , 使每个节点都指向它自己 

for (int i=1; i<k; i++)

if (_union(mark[i][0],mark[i][1])) //合并函数, 使两个节点合并

{

flag=0;

break;

}

if (flag)  //  下面的是  check看是不是一颗树 不然就成深林了

{

int forefather=_find(mark[1][0]);

for (int i=1; i<k; i++)

if (_find(mark[i][0])!=forefather||_find(mark[i][1])!=forefather)

{

flag=0;

break ;

}

}

}

printf("%s\n", flag?"Yes":"No"); //样例输出

}

return 0;

}

最后给大家留了个链接 ,是我做的word, 谢谢!

我会留在我博客里的,有兴趣的可以关注一下。

 

转载于:https://my.oschina.net/kensoon/blog/704625

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chiyan2683/article/details/100649953

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue