POJ 1308 Is It A Tree?--题解报告
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 31092 | Accepted: 10549 |
Description
There is exactly one node, called the root, to which no directed edges point.
Every node except the root has exactly one edge pointing to it.
There is a unique sequence of directed edges from the root to each node.
For example, consider the illustrations below, in which nodes are represented by circles and edges are represented by lines with arrowheads. The first two of these are trees, but the last is not. 
In this problem you will be given several descriptions of collections of nodes connected by directed edges. For each of these you are to determine if the collection satisfies the definition of a tree or not.
Input
Output
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
Case 1 is a tree.
Case 2 is a tree.
Case 3 is not a tree. 题意很简单,输入一组数据表示存在父子节点关系的点的编号,判断是否为树 方法一:运用并查集,将有连接关系的点放入同一集合内,判断是否出现环和多个根。如果没有则为树。具体见代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
struct edge
{
int s,t;
}E[];
int par[],Rank[];
int k=,n=,ne=,num=;
bool used[];//used用于记录1到出现的最大数字之间的数字是否使用过
void init(){
memset(Rank,,sizeof(Rank));
for(int i=;i<=;i++)
par[i]=i;
} int Find(int i){
if(par[i]==i)return i;
else return Find(par[i]);
}
bool same(int x,int y){
return Find(x)==Find(y);
} void unite(int x,int y){
if(same(x,y))return;
else{
x=Find(x);
y=Find(y);
if(Rank[x]<Rank[y])
par[x]=y;
else{
par[y]=x;
if(Rank[x]==Rank[y]) Rank[x]++;
}
}
}
void tree(){
init();
bool flag=true;
int now=-;
for(int i=;i<=n;i++){
if(!same(E[i].s,E[i].t)){//判断是否首尾相连成环
unite(E[i].s,E[i].t);
}
else{
flag=false;
break;
}
} for(int i=;i<=ne;i++){
if(used[i]==true&&par[i]==i){//判断根的数目,如果多于1则不是树
num++;
if(num==){
flag=false;
break;
}
}
}
if(flag)printf("Case %d is a tree.\n",++k);
else printf("Case %d is not a tree.\n",++k);
} int main(){
int x,y;
while(scanf("%d%d",&x,&y)){
if(x==-&&y==-) break;
else if(x!=&&y!=){
++n;
E[n].s=y;
E[n].t=x;
ne=max(x,max(ne,y));
used[x]=true;//因为题目没有给出数目采用这种方法判断需要的循环次数
used[y]=true;
}
else{
tree();
memset(used,,sizeof(used));
init();
n=;
ne=;
num=;
}
}
return ;
}
方法二:利用树的性质:(1)点数=边数+1,这个性质可以去掉多根的情况。(2)一个点最多有一个父节点,这个性质可以去掉成环的情况,具体代码如下:
#include<cstdio>
#include<cstring> using namespace std; int x,y,a[]={},m,n,flag;
int main()
{
int k=;
while(scanf("%d%d",&x,&y))
{
if(x==-&&y==-) break;
m++;//输入一组边数+1
if(a[y]==){flag=;}//如果y已经作为过子节点,再一次做子节点,说明出现两个父节点(也可能是重复的边,也不是树),不是树
if(!a[x]&&x){a[x]=;n++;}//1为父节点,2为子节点标记各个点,点数+1
if(!a[y]&&y){a[y]=;n++;}
if(x==&&y==)
{
if(!flag&&((n==m)||(n==&&m==))) printf("Case %d is a tree.\n",k++);//由于0 0也算入边内,因此m为边数+1,m==n;需特判空树
else printf("Case %d is not a tree.\n",k++);
m=,n=,flag=;
memset(a,,sizeof(a));
}
}
return ;
}
方法二由@刘靖尧 金鱼同学提供POJ 1308 Is It A Tree?--题解报告的更多相关文章
- POJ 1308 Is It A Tree? 解题报告
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 32052 Accepted: 10876 D ...
- HDU 1325,POJ 1308 Is It A Tree
HDU认为1>2,3>2不是树,POJ认为是,而Virtual Judge上引用的是POJ数据这就是唯一的区别....(因为这个瞎折腾了半天) 此题因为是为了熟悉并查集而刷,其实想了下其实 ...
- POJ 1308 Is It A Tree?和HDU 1272 小希的迷宫
POJ题目网址:http://poj.org/problem?id=1308 HDU题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1272 并查集的运用 ...
- POJ 1308 Is It A Tree? (并查集)
Is It A Tree? 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/M Description A tree is a w ...
- hdu 1325 && poj 1308 Is It A Tree?(并查集)
Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a ...
- POJ 1308 Is It A Tree?
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18778 Accepted: 6395 De ...
- HDU ACM 1325 / POJ 1308 Is It A Tree?
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- POJ 1308 Is It A Tree? (并查集)
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24237 Accepted: 8311 De ...
- 并查集判树 poj 1308
例题: poj 1308 题目大意比较简单,对任意两个点,有且仅有一条道路,也就是一棵树. 题解:一棵树中,肯定是不能有环的,而且只能由一个根节点.(没认真读题,只知道在那里判环....),所以这个题 ...
随机推荐
- 函数之局部变量和使用global语句
局部变量当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的.这称为变量的 作用域 .所有变量的作用域是它们被定义的块,从它们的名称被定义 ...
- Laravel Cache 使用
在项目中使用 laravel 的 cache 时,使用下面形式方法: $value = Cache::remember('users', $minutes, function() { return D ...
- (简单) LightOJ 1074 Extended Traffic,SPFA+负环。
Description Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked ...
- pyhton字符编码问题--decode和encode方法
1 decode和encode方法 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成uni ...
- Linux ALSA声卡驱动之二:声卡的创建
1. struct snd_card 1.1. snd_card是什么 snd_card可以说是整个ALSA音频驱动最顶层的一个结构,整个声卡的软件逻辑结构开始于该结构,几乎所有与声音相关的逻辑设备都 ...
- STM32F412应用开发笔记之八:迪文串口屏显示驱动
迪文的显示屏使用起来比较方便,其使用串口通讯,即可支持RS232,又可以支持TTL电平.在NUCLEO-F412ZG实验板上,USART2已经引到了CN9上,我们就利用USART2来实现与迪文串口屏的 ...
- linux 更换yum源
1.进入存放源配置的文件夹 cd /etc/yum.repos.d 2.备份默认源 mv ./CentOS-Base.repo ./CentOS-Base.repo.bak 3.使用wget下载163 ...
- Led控件
在 WindowMobile 上的模拟LED 显示屏插件 一个简单Led控件 一个经典的控制Led的单片机程序 Led控件(2)——Led显示屏模拟
- LINUX 无法登入系统(2017-1-16)
很好的博文:http://blog.csdn.net/caizi001/article/details/38659189
- 华硕A450c详细清灰拆机教程
很久都想写点东西,但又无从下笔. 上次把自己的笔记本清了灰,这次有时间就整理一下,随便作为我的第一次随笔. 准备:笔记本(我的是华硕A450c),拆机工具(螺丝刀等) 温馨提示:要慢点 1,先翻开笔记 ...