题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1325

题意是每次输入一对数字n,m表示一条树边,并且n是m的父亲,直到n==0&&m==0,表示这一组数据结束输入,当某组数据第一条边n,m都是-1时结束程序,我表达不太行。

我们要判断每一组数据输入的这些边是不是可以构成一棵树。

首先如果这时一棵树,我们可以知道它的一些性质,比如:

除了根节点入度为0,其他点的入度都为1。

边的数目加1等于点的数目

树上的点是两两连通的。

那么我们只需要记录每个点的入度(是不是大于1),记录边数和点数,最后判断这是不是一棵树(连通),而不是森林。

这里需要注意空树也是树。

我的代码写的有点low:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 100005
/*struct point{
int u,w;
};
bool operator <(const point &s1,const point &s2)
{
if(s1.w!=s2.w)
return s1.w>s2.w;
else
return s1.u>s2.u;
}*/
bool vis[maxn];
int pre[maxn],in[maxn];
int n,m,k,t;
int edge_num,point_num,flag,digit;//digit在这里是随便记录一个树上面的点,后面好判断连通
void init()
{
for(int i=;i<maxn;i++)
pre[i]=i;
memset(vis,false,sizeof(vis));
memset(in,,sizeof(in));
edge_num=point_num=;
flag=;
}
int find(int a)//找祖先节点
{
if(pre[a]==a)
return a;
return pre[a]=find(pre[a]);
}
void combine(int a,int b)//连接两个集合
{
int x=find(a);
int y=find(b);
if(x!=y)
pre[x]=y;
}
void addedge(int a,int b)//添加边
{
if(!vis[a])
{
digit=a;
vis[a]=true;
point_num++;
}
if(!vis[b])
{
vis[b]=true;
point_num++;
}
edge_num++;//边加
in[b]++;//入度加
if(in[b]>)
flag=;
combine(a,b);
}
int jug()//判断是否是数
{
if(flag)
return false;
if(edge_num+!=point_num)
return false;
for(int i=;i<maxn;i++)
{
if(vis[i]&&find(digit)!=find(i))
return false;
}
return true;
}
int main()
{
int num=;
while(scanf("%d%d",&n,&m))
{
if(n<||m<)
break;
if(n==&&m==)//特殊情况,空树
{
printf("Case %d is a tree.\n",++num);
continue;
}
init();
addedge(n,m);
while(scanf("%d%d",&n,&m))
{
if(n==&&m==)
break;
addedge(n,m);
}
if(jug())
printf("Case %d is a tree.\n",++num);
else
printf("Case %d is not a tree.\n",++num);
}
return ;
}

并查集和树的一些性质 hdu1325的更多相关文章

  1. BZOJ3211 花神游历各国 并查集 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...

  2. HDU 1116 Play on Words(并查集和欧拉回路)(有向图的欧拉回路)

    Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  3. LeetCode刷题总结-排序、并查集和图篇

    本文介绍LeetCode上有关排序.并查集和图的算法题,推荐刷题总数为15道.具体考点分析如下图: 一.排序 1.数组问题 题号:164. 最大间距,难度困难 题号:324. 摆动排序 II,难度中等 ...

  4. 22.1.22 并查集和KMP算法

    22.1.22 并查集和KMP算法 1.并查集结构 1)实现: 并查集有多种实现方式,例如向上指的图的方式,数组的方式等等.其根本思想就在于准确记录某个节点的根节点,这个这种记录就能够很快的实现并查集 ...

  5. BZOJ-3211花神游历各国 并查集+树状数组

    一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...

  6. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

  7. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

  8. 无限极分类php实现—查子孙树、家谱树

    1.本文更新日期:2018/05/20 , 亲测可用,在原有基础上进行增强和 详细化 . 2.面包屑导航 和 子孙树 效果图如下: 3.代码: <?php // 无限级分类中,查家谱树(面包屑导 ...

  9. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

随机推荐

  1. js五子棋游戏

    //code <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <ti ...

  2. 白鹭引擎 - 事件机制 ( Event, addEventListener, dispatchEvent )

    1, 自定义事件, MyEvent class MyEvent extends egret.Event { /** * 一般会定义一个 DATA 字段作为事件 * 绑定事件监听器时, 一般用 类.DA ...

  3. docker利用Dockerfile来制作镜像

    在前面的例子(docker tomcat镜像制作)中,我们从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低.所以就需要一 种文件或脚本,我 ...

  4. 关于spire wb.SaveToPdf(f_pdf) excell 转为pdf 乱码问题

    excell 可以合并单元格,但是在单元格内容不要用 alt+enter换行,否则就会出现乱码.

  5. 机器学习进阶-疲劳检测(眨眼检测) 1.dist.eculidean(计算两个点的欧式距离) 2.dlib.get_frontal_face_detector(脸部位置检测器) 3.dlib.shape_predictor(脸部特征位置检测器) 4.Orderdict(构造有序的字典)

    1.dist.eculidean(A, B) # 求出A和B点的欧式距离 参数说明:A,B表示位置信息 2.dlib.get_frontal_face_detector()表示脸部位置检测器 3.dl ...

  6. html表单中get与post之间的区别

    当用户在 HTML 表单 (HTML Form) 中输入信息并提交之后,有两种方法将信息从浏览器传送到 Web 服务器 (Web Server). 一种方法是通过 URL,另外一种是在 HTTP Re ...

  7. JAVA8-待续

    1. 函数式编程,因为在并发和时间驱动编程中的优势,函数式编程又逐渐流行起来 以前是实现一个比较器需要实现Comparator接口,并重写compare方法,以下为两种实现方法(类似还有线程,事件等) ...

  8. Haskell语言练习

    Monad inc n = Just (n + 1) add1 n = [n + 1] main = do print $ Nothing >> (Just 0) -- Nothing p ...

  9. python学习笔记之斐波拉契数列学习

    著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 如果用Python的列表生成式, ...

  10. Linux 多进程实现方法

    1.需求 查找192.168.0.*网段中所有未使用过的IP 2.实现     我们知道查找未使用IP的方法可以使用ping命令完成.对于单个IP的判断,使用命令如下 $ 192.168.0.1 PI ...