并查集浅析(poj 1308)

来源:互联网 发布:js 字符串转date 编辑:程序博客网 时间:2024/05/22 01:32

转载一篇讲解,讲的非常透彻:http://blog.csdn.net/pure_life/article/details/2922118

POJ 1308

形成树的条件:(1) 只有一个根 (2) 非根节点入度只能为1

#include <stdio.h>#include <memory.h>const int MAX_SIZE = 105;int parent[MAX_SIZE];bool flag[MAX_SIZE];void make_set(){  //初始化for(int x = 1; x < MAX_SIZE; x ++){parent[x] = x;flag[x] = false;}}int find_set(int x){   //寻找根节点,带路径压缩if(x != parent[x])parent[x] = find_set(parent[x]);return parent[x];}void union_set(int x, int y){  //合并x = find_set(x);y = find_set(y);if(x == y) return;parent[y] = x;}bool single_root(int n){   //判断是不是只有一个根,条件(1)int i = 1;while (i <= n && !flag[i]){++i;}int root = find_set(i);while (i <= n){if (flag[i] && find_set(i) != root){return false;}++i;}return true;}int main(){int x, y;bool is_tree = true;int range = 0;int idx = 1;make_set();while (scanf("%d %d", &x, &y) != EOF){if (x < 0 || y < 0){break;}if (x == 0 || y == 0){if (is_tree && single_root(range)){printf("Case %d is a tree.\n", idx++);}else{printf("Case %d is not a tree.\n", idx++);}is_tree = true;range = 0;make_set();continue;}if (!is_tree){continue;}range = x > range ? x : range;range = y > range ? y : range;flag[x] = flag[y] = true;if (find_set(x) == find_set(y)){  //如果两者属于一个集合(也就是有共同祖先),并且两者还有父子关系,那么无法形成树,条件2is_tree = false;}union_set(x, y);}return 0;}</span>


原创粉丝点击