连通块(并查集求解)
作者:
husheng
,
2022-05-23 12:15:20
,
所有人可见
,
阅读 228
实现思路:先要维护并查集,我们先遍历一下地图,找到值为W的位置,然后看其上下左右4个方向,如果某个方向没有越界
且值也为W的话,那么说明这2个位置是连通的,此时我们将其合并成一个集合。一直找下去,直至地图遍历完后,我们已经
将所有相连的位置都合并成集合了,最后再重新遍历一下地图,如果某个点的值为W且这个点的根节点为它自己的话(即这
个点为该集合的根节点,也可以说成这个点是这个集合的代表元素),那么连通块数量加1,遍历完以后输出连通块总数即
可
import java.util.Scanner;
public class Main {
static int n,m;
static char[][] arr;
static int[] p;
static int[] dx= {-1,1,0,0};
static int[] dy= {0,0,-1,1};
public static int get(int x,int y) {
return m*x+y;
}
public static int find(int x) {
if(p[x]!=x) {
p[x]=find(p[x]);
}
return p[x];
}
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
n=input.nextInt();
m=input.nextInt();
arr=new char[n][m];
p=new int[n*m+5];
for(int i=0;i<n;i++) {
arr[i]=input.next().toCharArray();
}
for(int i=0;i<n*m;i++) {
p[i]=i;
}
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
if(arr[i][j]=='W') {
for(int k=0;k<4;k++) {
int x=i+dx[k];
int y=j+dy[k];
if(x>=0&&x<n&&y>=0&&y<m&&arr[x][y]=='W') {
int a=get(i,j);
int b=get(x,y);
a=find(a);
b=find(b);
if(a!=b) {
p[a]=b;
}
}
}
}
}
}
int cnt=0;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
if(arr[i][j]=='W') {
int a=get(i,j);
if(find(a)==a) {
cnt++;
}
}
}
}
System.out.println(cnt);
}
}