【并查集】判断是否为树
来源:互联网 发布:java构造函数调用 编辑:程序博客网 时间:2024/04/28 05:01
【问题描述】
树是一种大家都不陌生的数据结构,它有可能是一颗空树或是一些满足要求的节点连接而成的有向边的集合。
一棵树只有一个根节点,根节点没有指向它的边。
除了根节点的每一个节点都只有一条边指向它。
出现环的图都不是树。
对一些节点连接而成的有向边的集合进行判定,判定每一组的输入数据构成的图是否是一棵树。
【输入】
每输入一对都为0的数时,表示一组数据输入完毕。每条边由一对正整数表示,第一个数为有向边的起始点,第二个数为有向边的终止点。一对负数的输入表示输入的结束。
【输出】
每组测试数据输出一行判定结果,若输入的图为树,则输出“Case k is a tree.”,否则输出“Case k is not a tree.”。其中k表示每组数据的编号(编号从1开始)。
【解题报告】
运用并查集可以判定一个图是否为树。
根据树的定义与特点,需考虑的情况有:
(1)树中节点至多只能有一个父节点;
(2)树中不能出现环;
(3)构成的图只能有一个根节点,否则构成的将是森林而不是一棵树。
通过观察输入输出可知,题中编号是随即的,所以在编程中要对出现的点标记才能判断。
Step1:对每对输入的根节点标记表示这些节点出现过,进行并操作。并操作时两个节点不能有相同的根节点否则将构成环;假设b节点要接到a上,则要保证b节点是一个根节点,否则若进行并操作,b将会有两个父节点;若无以上情况,则可以合并两棵树。
Step 2:每组数据输入结束后,要计算整个图中的根节点总数,若根节点总数不为1,则构成的图不是一棵树。
Step 3:根据以上判断就可以输出结果了,每组结果输出后要初始化数据。
#include <stdio.h>#include <stdlib.h>#include <string.h>int father[1000000], flag[1000000];int findset(int x)//查{if(x != father[x])father[x]=findset(father[x]);//路径压缩return father[x];}int unionset(int a, int b)//并{int x=findset(a);int y=findset(b);if(y != b)//b连接在a上,要保证b是个根节点,否则b将有两个父节点return 1;if(x == y)//如果a,b在同一棵树中,若再进行并操作就会产生环return 1;elsefather[y]=x;//若无以上情况,则可以合并两棵树return 0;}int main(){int a, b, key=0, p=1, i, max=0, t=0;for(i=1; i<=999999; i++)father[i]=i;memset(flag, 0, sizeof(flag));while(1){scanf("%d%d", &a, &b);if(a>max) max=a;if(b>max) max=b;if(a<=-1 && b<=-1) break;if(a==0 && b==0){for(i=1; i<=max; i++){if(flag[i]==1 && father[i]==i)t++;if(t>=2) break;}if(key>0 || t>=2)printf("Case %d is not a tree.\n", p++);elseprintf("Case %d is a tree.\n", p++);for(i=1; i<=999999; i++)father[i]=i;key=0; t=0; max=0;memset(flag, 0, sizeof(flag));continue;}flag[a]=1;flag[b]=1;//对输入的编号标记key+=unionset(a,b);//若出现不合法的情况,key的值会大于0}}
- 【并查集】判断是否为树
- 【并查集】判断是否为树
- 用并查集判断是否为树
- zoj1268-简单并查集(判断是否为一颗树)
- HDU1325并查集判断是否为一棵树
- 并查集的应用(2)——判断是否为树
- hdoj1325 Is It A Tree? 判断是否为树 并查集
- [POJ 1308]Is It A Tree?(并查集判断图是否为一棵有根树)
- 并查集判断树
- LA3644 利用并查集判断是否有环
- HDU 1325(并查集判断一个图是否是一棵树)
- 并查集-判断无向图是否存在环
- 并查集---判断图中是否存在环
- 使用并查集判断无向图是否连通
- HUD 1272 (并查集判断是否有环)
- 用并查集判断是否是一棵树(1325)
- GOJ1446 并查集判断逻辑错误(是否说谎)
- HDU-1863(最小生成树+并查集判断是否连通)
- 动态描述性编程,实现计算器6位以内不同的随机数,包含小数和正负数的加减乘除运算
- linux eval命令参数及用法
- ubuntu下用图形化比较工具Meld
- Could not find class 'org.ksoap2.serialization.SoapObject', referenced from method cn.edu.bzu.soap.S
- Zdenek Kalal
- 【并查集】判断是否为树
- 代码腐烂
- 应用程序的关闭
- ubuntu安装java JDK
- Win32 程序 控件风格和预览不一样的问题
- 左连接查询
- 复制文件句柄dup2 函数
- 嵌入式系统开发:C语言中的位结构体
- windows性能监视器API