package com.liang.poj;
import java.util.Scanner;
public class Test1308_Union_Fand_set {
static int N = 100001;
static int[] node = new int[N];
static int[] rank = new int[N];
static int count = 1;
static boolean tag = true;
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
makeSet();
while (scan.hasNext()) {
int a = scan.nextInt();
int b = scan.nextInt();
if (a == -1 && b == -1) {
break;
}
if (a == 0 && b == 0) {
if (tag) {
if (!judge()) {
System.out.println("Case " + count++ + " is not a tree.");
} else {
System.out.println("Case " + count++ + " is a tree.");
}
} else {
System.out.println("Case " + count++ + " is not a tree.");
}
makeSet();
} else {
merge(a, b);
}
}
}
public static void makeSet() { // 初始化单元素集合
tag = true;
for (int i = 1; i < N; i++) {
node[i] = 0;
rank[i] = 0;
}
}
public static int find(int x) { // 带路径压缩的查找
if (node[x] == 0) {
node[x] = x;
return x;
} else {
if (x != node[x]) {
x = find(node[x]);
}
return x;
}
}
public static void merge(int a, int b) { // 合并集合a,集合b
int fa = find(a);
int fb = find(b);
if (fa == fb) {
if (fa == 0 && fb == 0) {
if (rank[fa] >= rank[fb]) {
node[fb] = fa;
rank[fa]++;
} else {
node[fa] = fb;
rank[fb]++;
}
} else {
tag = false;
}
} else {
if (rank[fa] >= rank[fb]) {
node[fb] = fa;
rank[fa]++;
} else {
node[fa] = fb;
rank[fb]++;
}
}
}
public static boolean judge() {
int sum = 0;
for (int i = 1; i < node.length; i++) {
if (node[i] == 0) {
continue;
} else {
if (i == node[i]) {
sum++;
}
if (sum >= 2) {
return false;
}
}
}
return true;
}
}
本文详细介绍了并查集算法的实现及其应用。通过一个具体的Java程序示例,展示了如何使用并查集解决图论中判断是否形成树的问题。文章包括了初始化单元素集合、查找操作(含路径压缩)、集合合并及最终的判断条件等关键步骤。
134

被折叠的 条评论
为什么被折叠?



