浙江财经大学
信息管理与工程学院

HDU 1198 Farm Irrigation

本文由 Ocrosoft 于 2016-08-13 16:18:07 发表

Farm Irrigation

Problem Description

Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.

Figure 1
Benny has a map of his farm, which is an array of marks denoting the distribution of water pipes over the whole farm. For example, if he has a map 
ADC
FJK
IHE
then the water pipes are distributed like 

Figure 2
Several wellsprings are found in the center of some squares, so water can flow along the pipes from one square to another. If water flow crosses one square, the whole farm land in this square is irrigated and will have a good harvest in autumn. 
Now Benny wants to know at least how many wellsprings should be found to have the whole farm land irrigated. Can you help him? 
Note: In the above example, at least 3 wellsprings are needed, as those red points in Figure 2 show.

Input

There are several test cases! In each test case, the first line contains 2 integers M and N, then M lines follow. In each of these lines, there are N characters, in the range of ‘A’ to ‘K’, denoting the type of water pipe over the corresponding square. A negative M or N denotes the end of input, else you can assume 1 <= M, N <= 50.

Output

For each test case, output in one line the least number of wellsprings needed.

Sample Input

2 2
DK
HF

3 3
ADC
FJK
IHE

-1 -1

Sample Output

2
3

Solution

题意:土地有上面的11中类型,每组测试数据会给出这些块组成的n*m的土地,蓝色的部分是水渠,问要修多少水井能灌溉所有的土地。
思路:只要两块土地的水渠能够相连,那么这两块地可以共用一个水井,所以这个题目就是并查集了。

//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize("Og")
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <stack>
#include <queue>
#include <ctime>
#include <string>
#include <cstdio>
#include <vector>
#include <cctype>
#include <climits>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ms(a) memset(a,0,sizeof(a))
typedef long long ll;
const int INF = INT_MAX;
const int MAXN = 500 + 10;
using namespace std;
int link[11][4] = {
	{ 1,1,0,0 },{ 0,1,1,0 },
	{ 1,0,0,1 },{ 0,0,1,1 },
	{ 0,1,0,1 },{ 1,0,1,0 },
	{ 1,1,1,0 },{ 1,1,0,1 },
	{ 1,0,1,1 },{ 0,1,1,1 },
	{ 1,1,1,1 }
};
char mp[MAXN][MAXN];
int pre[MAXN*MAXN], n, m;
int find(int x)
{
	if (pre[x] != x)pre[x] = find(pre[x]);
	return pre[x];
}
int cnt;
void Union(int ax, int ay, int bx, int by, bool dir)
{
	if (bx>n || by>m)return;
	bool mark = false;
	int ta, tb;

	ta = mp[ax][ay] - 'A';
	tb = mp[bx][by] - 'A';

	if (dir)
	{
		if (link[ta][3] && link[tb][1])mark = true;
	}
	else
	{
		if (link[ta][2] && link[tb][0])mark = true;
	}

	if (mark)
	{
		int fx = find((ax - 1)*m + ay);
		int fy = find((bx - 1)*m + by);
		if (fx != fy)
		{
			pre[fy] = fx;
			--cnt;
		}
	}
}
int main()
{
	while (cin >> n >> m)
	{
		if (n == -1 && m == -1)break;
		cnt = n*m;
		for (int i = 1; i <= n*m; i++)pre[i] = i;

		for (int i = 1; i <= n; i++)cin >> mp[i] + 1;

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
			{
				Union(i, j, i + 1, j, 1);
				Union(i, j, i, j + 1, 0);
			}
		printf("%d\n", cnt);
	}
	return 0;
}

欢迎分享与转载,请保留链接与出处。Ocrosoft » HDU 1198 Farm Irrigation

点赞 (0)or拍砖 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址