题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198
题目大意:用并查集判断连通性,这个简单,如何把数据输入比较麻烦,如何把图中的管道表示成图,参考了别人的很多博客终于明白,用0,1来代表水管上下左右是否联通。
代码:
import java.util.Scanner;
//用并查集判断连通性,这个简单,如何把数据输入比较麻烦,用0,1来代表水管上下左右是否联通。
public class Main {
static int m,n,cnt;
static int maxn=550*550;
static int p[]=new int[maxn];
static int find(int x){
return x==p[x]?x:(p[x]=find(p[x]));
}
static void merge(int ax,int ay,int bx,int by,boolean flag){
if(bx>=m||by>=n)
return;
int ta=map[ax][ay]-'A';
int tb=map[bx][by]-'A';
boolean mark=false;
if(flag){
if (land[ta][1]==1&&land[tb][0]==1) //判断上下管道是否连接
mark=true;
}else{
if (land[ta][3]==1&&land[tb][2]==1) //判断左右管道是否连接
mark=true;
}
if(mark){
int x=find(ax*n+ay);
int y=find(bx*n+by);
if(x!=y){
p[x]=y;
cnt--;
}
}
}
static void init(){
for (int i = 0; i <=n*m ; i++) {
p[i]=i;
}
cnt=m*n;
}
static int land[][]={{1,0,1,0},{1,0,0,1},{0,1,1,0},{0,1,0,1},{1,1,0,0},{0,0,1,1},{1,0,1,1},{1,1,1,0},
{0,1,1,1},{1,1,0,1},{1,1,1,1}};
static char map[][]=new char[550][550];
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(true){
m=sc.nextInt();
n=sc.nextInt();
if(m<0&&n<0){
break;
}
init();
for (int i=0;i<m;i++){
String s=sc.next();
for (int j=0;j<n;j++){
map[i][j]=s.charAt(j);
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
merge(i,j,i,j+1,false);//横向判断是否联通
merge(i,j,i+1,j,true);//竖直方向判断是否联通
}
}
System.out.println(cnt);
}
}
}