声明:本文仅作为算法题目分享和学习交流使用,若内容存在侵权行为,请及时私信联系,我们将立即删除。
问题描述(回忆题目,可能存在不完整)
有 n 个城市,初始时所有城市之间都没有建立联系。系统会进行 q 次操作,操作分为两种类型:
-
建立联系(操作类型为 1):在城市 x 和城市 y 之间建立联系
-
查询联系(操作类型为 2):查询城市 x 和城市 y 是否已经建立了联系(包括直接或间接联系)
对于每个查询操作,如果两个城市已经建立了联系,则输出 "Yes x y"(x 和 y 是查询的两个城市);如果没有建立联系,则输出 "No"。
输入格式
第一行包含两个整数 n 和 q,分别表示城市的数量和操作的数量。
接下来 q 行,每行包含三个整数:
-
第一个整数是操作类型 a(1 或 2)
-
第二个整数是城市 x
-
第三个整数是城市 y
输出格式
对于每个查询操作(操作类型为 2),输出一行结果:
-
如果两个城市已建立联系,输出 "Yes x y"
-
如果两个城市未建立联系,输出 "No"
仅供参考(不是官方正确答案)
import java.util.*;
public class Main {
private static int[] parent;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取城市数量和操作数量
int n = scanner.nextInt();
int q = scanner.nextInt();
// 初始化并查集
parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i; // 初始时每个城市都是独立的,父节点指向自己
}
// 处理每个操作
for (int i = 0; i < q; i++) {
int operation = scanner.nextInt();
int x = scanner.nextInt();
int y = scanner.nextInt();
// 城市编号从1开始,调整为从0开始
x--;
y--;
if (operation == 1) {
// 建立联系操作:合并两个城市
union(x, y);
} else if (operation == 2) {
// 查询联系操作:检查两个城市是否连通
if (find(x) == find(y)) {
// 注意输出时要还原城市编号(从1开始)
System.out.println("Yes " + (x + 1) + " " + (y + 1));
} else {
System.out.println("No");
}
}
}
scanner.close();
}
// 查找根节点(带路径压缩)
private static int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // 路径压缩:直接连接到根节点
}
return parent[x];
}
// 合并两个集合
private static void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
parent[rootY] = rootX; // 将y的根节点连接到x的根节点
}
}
}
932

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



