HOJ 1198 Farm Irrigation (并查集)

我直接用了结构体进行操作,看起来有点复杂,其实不难,过程都写在注释了。

#include
#include
#pragma warning(disable:4996)
using namespace std;
const int NN = 55;

//因为用的是二维数组这样的数据,故使用二元组的结构体存储根节点
typedef struct point
{
	int x, y;
}point;

typedef struct node
{
	int up, down, left, right;//每一块农田的管道是否能够通向这一各方向,1表示可通,0反之
	int flag;//0表示未到达过
}node;

int n, m;
point f[NN][NN];
node a[NN][NN];

//根据输入的字母对数据进行初始化
node get(char c)
{
	node x;
	x.up = x.down = x.left = x.right = 1;
	x.flag = 0;
	switch (c)
	{
	case 'A':
		x.right = 0;
		x.down = 0;
		break;
	case 'B':
		x.left = 0;
		x.down = 0;
		break;
	case 'C':
		x.up = 0;
		x.right = 0;
		break;
	case 'D':
		x.up = 0;
		x.left = 0;
		break;
	case 'E':
		x.left = 0;
		x.right = 0;
		break;
	case 'F':
		x.up = 0;
		x.down = 0;
		break;
	case 'G':
		x.down = 0;
		break;
	case 'H':
		x.right = 0;
		break;
	case 'I':
		x.up = 0;
		break;
	case 'J':
		x.left = 0;
		break;
	default:
		break;
	}
	return x;
}

//根节点寻找方法上和一维一样,二维只是数据类型改变一下
point find(int x, int y)
{
	point p;
	p.x = x;
	p.y = y;
	if (x == f[x][y].x && y == f[x][y].y) return p;
	f[x][y] = find(f[x][y].x, f[x][y].y);
	return f[x][y];
}

int mer(point x, point y)
{
	x = find(x.x, y.y);
	y = find(y.x, y.y);
	if (x.x != y.x || x.y != y.y)
		f[x.x][x.y] = y;
	return 1;
}

int search(node p, int x, int y)
{
	a[x][y].flag = 1;//这块农田已经到达过了,标记,下次遇到这块就不需要重复检索了

	//检索相邻块可接通必须满足该块与目标块有接通的管道,且未曾到达过目标块,四个方向操作一样
	if (p.up == 1 && x - 1 >= 1 && a[x - 1][y].flag == 0 && a[x - 1][y].down == 1)
	{
		mer(f[x][y], f[x - 1][y]);//进行标记
		search(a[x - 1][y], x - 1, y);//连通
	}
	if (p.down == 1 && x + 1 <= m && a[x + 1][y].flag == 0 && a[x + 1][y].up == 1)
	{
		mer(f[x][y], f[x + 1][y]);
		search(a[x + 1][y], x + 1, y);
	}
	if (p.left == 1 && y - 1 >= 1 && a[x][y - 1].flag == 0 && a[x][y - 1].right == 1)
	{
		mer(f[x][y], f[x][y - 1]); 
		search(a[x][y - 1], x, y - 1);
	}
	if (p.right == 1 && y + 1 <= n && a[x][y + 1].flag == 0 && a[x][y + 1].left == 1)
	{
		mer(f[x][y], f[x][y + 1]);
		search(a[x][y + 1], x, y + 1);
	}
	return 1;
}

int main()
{
	char c;
	int num;
	while (cin >> m >> n)
	{
		if (m < 0 && n < 0) break;
		num = 0;
		for (int i = 1; i <= m; i++)
			for (int j = 1; j <= n; j++)
			{//初始化
				f[i][j].x = i;
				f[i][j].y = j;
				cin >> c;
				a[i][j] = get(c);
			}
		for (int i = 1; i <= m; i++)
			for (int j = 1; j <= n; j++)
				if (a[i][j].flag == 0)
				{
					search(a[i][j], i, j);
					num++;
				}
		cout << num << endl;
	}
	return 0;
}

PS:若有错误或者可改进的地方欢迎大家指出。_

你可能感兴趣的:(HOJ 1198 Farm Irrigation (并查集))