「java并查集」java并查集算法
今天给各位分享java并查集的知识,其中也会对java并查集算法进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、一道算法题,算法好或者搞ACM的童鞋看过来~
- 2、LeetCode 力扣官方题解 - 1020. 飞地的数量
- 3、ACM 1233 还是畅通工程,我用的是并查集的思路,其中排序用的冒泡,提交显示超时,求指导,问题出在哪
- 4、判断图中两点是否相通 java
一道算法题,算法好或者搞ACM的童鞋看过来~
你好,我已经ac了,下面是ac代码
思路就是简单并查集
41549 wujianan2007 1012 Accepted 32148 kb 1060 ms Java/Edit 2012-02-01 00:05:46
import java.math.*;
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
public static int father[] = new int[1005];
public static int getFather(int x) {
int ret = x;
while (ret != father[ret]) {
father[ret] = father[father[ret]];
ret = father[ret];
}
return ret;
}
public static void union(int a, int b) {
father[getFather(b)] = father[getFather(a)];
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n, m;
while (true) {
n = cin.nextInt();
if (n == 0) {
break;
}
for (int i = 1; i = n; i++) {
father[i] = i;
}
m = cin.nextInt();
while (m 0) {
int a, b;
a = cin.nextInt();
b = cin.nextInt();
union(a, b);
m--;
}
boolean t[] = new boolean[1005];
int cnt = 0;
for (int i = 1; i = n; i++) {
t[i] = false;
}
for (int i = 1; i = n; i++) {
t[getFather(i)] = true;
}
for (int i = 1; i = n; i++) {
if (t[i] == true) {
cnt++;
}
}
System.out.printf("%d\n", cnt - 1);
}
}
}
LeetCode 力扣官方题解 - 1020. 飞地的数量
题目描述
给你一个大小为 m x n 的二进制矩阵 grid,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。
一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。
返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。
示例 1:
示例 2:
提示:
根据飞地的定义,如果从一个陆地单元格出发无法移动到网格边界,则这个陆地单元格是飞地。因此可以将所有陆地单元格分成两类:第一类陆地单元格和网格边界相连,这些陆地单元格不是飞地;第二类陆地单元格不和网格边界相连,这些陆地单元格是飞地。
我们可以从网格边界上的每个陆地单元格开始深度优先搜索,遍历完边界之后,所有和网格边界相连的陆地单元格就都被访问过了。然后遍历整个网格,如果网格中的一个陆地单元格没有被访问过,则该陆地单元格不和网格的边界相连,是飞地。
代码实现时,由于网格边界上的单元格一定不是飞地,因此遍历网格统计飞地的数量时只需要遍历不在网格边界上的单元格。
代码
Java
C#
C++
C
Python3
Golang
JavaScript
复杂度分析
也可以通过广度优先搜索判断每个陆地单元格是否和网格边界相连。
首先从网格边界上的每个陆地单元格开始广度优先搜索,访问所有和网格边界相连的陆地单元格,然后遍历整个网格,统计飞地的数量。
代码
Java
C#
C++
C
Python3
Golang
JavaScript
复杂度分析
除了深度优先搜索和广度优先搜索的方法以外,也可以使用并查集判断每个陆地单元格是否和网格边界相连。
并查集的核心思想是计算网格中的每个陆地单元格所在的连通分量。对于网格边界上的每个陆地单元格,其所在的连通分量中的所有陆地单元格都不是飞地。如果一个陆地单元格所在的连通分量不同于任何一个网格边界上的陆地单元格所在的连通分量,则该陆地单元格是飞地。
并查集的做法是,遍历整个网格,对于网格中的每个陆地单元格,将其与所有相邻的陆地单元格做合并操作。由于需要判断每个陆地单元格所在的连通分量是否和网格边界相连,因此并查集还需要记录每个单元格是否和网格边界相连的信息,在合并操作时更新该信息。
在遍历网格完成并查集的合并操作之后,再次遍历整个网格,通过并查集中的信息判断每个陆地单元格是否和网格边界相连,统计飞地的数量。
代码
Java
C#
C++
C
Python3
Golang
JavaScript
复杂度分析
BY /
本文作者:力扣
ACM 1233 还是畅通工程,我用的是并查集的思路,其中排序用的冒泡,提交显示超时,求指导,问题出在哪
冒泡排序的时间复杂度是o(n^2),但是这个n指的是待排序的元素数量,这题里输入的点数是n,边数是n(n-1)/2,也就是n^2级别的边数,你这里要排序的是边,所以你用冒泡的时间复杂度就是o((n^2)^2)=o(n^4),这题n是100,n^4=10亿,一般OJ上1亿级别的复杂度就要跑接近1秒,你这单组数据就10亿,更别说题目还是多组数据,必然超时。这题要排序边的话必须要用o(nlogn)复杂度的排序,比如快速排序、堆排序和归并排序。
另外,除开排序,你这代码本身逻辑也有问题啊,你试一下这组数据:
4
1 2 1
1 3 7
1 4 8
2 3 9
2 4 7
3 4 1
答案应该是9。
你说用到并查集,我完全没看到并查集在哪里啊,这题就是个完全图的最小生成树,用prim算法会好一点,用kruskal算法的话并查集部分还要加上路径压缩才不会超时。你这里的town数组其实只有等于node和不等于node两种状态是有用的,node的值又不会变,这和boolean数组没什么实质的区别,这就是个标记数组,而不是并查集。
判断图中两点是否相通 java
目测很像朋友圈问题啊,首先数据结构有Point(x,y),line(Point a,Point b),应该是已知一些点,和一些线,若点A可通过一条或多条线到点B,则认为A、B连通,可用并查集解决,百度一下即可,应该是最后判断set(a)==set(b)则两点连通
java并查集的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java并查集算法、java并查集的信息别忘了在本站进行查找喔。