HDU 1198 Farm Irrigation(求集合个数)

题目地址:点击打开链接

思路:并查集,是一道好题,主要通过i*n+j来唯一标示每一个格子,其实i乘以大于等于n的每一个都可以唯一标识每一个格子,但考虑到pre数组是从1开始逐渐顺序递增的,所以只能通过乘以n来唯一标识,这样i*n+j的和也是从1开始逐渐顺序递增的

AC代码:

#include<stdio.h>
#include<iostream>
using namespace std;
char a[100][100];
int pre[3000],sum;
int find(int x)
{
	if(pre[x] == x)
		return x;
	return find(pre[x]);
}

void join(int x,int y)
{
	if(find(x) != find(y))
	{
		pre[find(x)] = find(y);
		sum--;
	}
}
int main()
{
	int m,n,i,j;
	while(scanf("%d%d",&m,&n))
	{
		sum = n*m;
		if(m == -1 && n == -1)
			break;
		for(i=0; i<m*n; i++)
		{
			pre[i] = i;
		}
		for(i=0; i<m; i++)
		{
			scanf("%s",a[i]);
		}
		for(i=0; i<m; i++)
		{
			for(j=0; j<n; j++)
			{
				if(i>0 && (a[i][j] == 'A' || a[i][j] == 'B' || a[i][j] == 'E' || a[i][j] == 'G' || a[i][j] == 'H' || a[i][j] == 'J' || a[i][j] == 'K'))
				{
					if(a[i-1][j] == 'C' || a[i-1][j] == 'D' || a[i-1][j] == 'E' || a[i-1][j] == 'H' || a[i-1][j] == 'I' || a[i-1][j] == 'J' || a[i-1][j] == 'K')//判断上下能否连通
						join(i*n+j,(i-1)*n+j);
				}
				if(j>0 && (a[i][j] == 'A' || a[i][j] == 'C' || a[i][j] == 'F' || a[i][j] == 'G' || a[i][j] == 'H' || a[i][j] == 'I' || a[i][j] == 'K'))
				{
					if(a[i][j-1] == 'B' || a[i][j-1] == 'D' || a[i][j-1] == 'F' || a[i][j-1] == 'G' || a[i][j-1] == 'I' ||a[i][j-1] == 'J' || a[i][j-1] == 'K')//判断左右能否连通
						join(i*n+j,i*n+j-1);
				}
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}


你可能感兴趣的:(HDU 1198 Farm Irrigation(求集合个数))