Farm Irrigation-----并查集+构图

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

扫描二维码关注公众号,回复: 8743293 查看本文章

3 3
ADC
FJK
IHE

-1 -1
Sample Output
2
3

题意:给你一个N*M的矩阵,由下面11种格子组成,每个格子互联的部分不同(比如A如果放在
C正下面,那么A与C是连通的),问你所给矩阵一共有几个连通分量。

解析:先把图构造出来,一共有n*m个联通分量,若有一次有效合并 连通分量-1
注意:遍历四个方向要与每个图所写的方向要一致
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=1e5+100;
int fa[N];
int dx[4]={-1,1,0,0}; //这边的方向要与下面的一致 
int dy[4]={0,0,-1,1};
//上下左右 
int con[11][4]={{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}};
int v[1005][1005];
int n,m;
char ch;
int find(int x)
{
	if(x!=fa[x]) return fa[x]=find(fa[x]);
	return fa[x];
}
int build(int a,int b)
{
	int x=find(a);
	int y=find(b);
	if(x!=y)
	{
		fa[x]=y;
		return 1;
	}
	return 0;
}
int main()
{
	while(~scanf("%d %d",&n,&m)&&n!=-1&&m!=-1)
	{
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				scanf(" %c",&ch);
				//cout<<ch<<endl;
				v[i][j]=ch-'A';
			}
		}
		for(int i=0;i<=n*m;i++) fa[i]=i;
		int sum=n*m;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int id=i*m+j;
				for(int k=0;k<4;k++)
				{
					int x=dx[k]+i;
					int y=dy[k]+j;
					int dir=(k%2==0) ? k+1: k-1;
					if(x>=0&&x<n&&y>=0&&y<m)
					{
						int did=x*m+y;
						if(con[v[i][j]][k]==1&&con[v[x][y]][dir]==1)
						{
							sum-=build(id,did);
						}
					}
				}
			}
		}
		cout<<sum<<endl;
	}
}

发布了284 篇原创文章 · 获赞 6 · 访问量 3763

猜你喜欢

转载自blog.csdn.net/qq_43690454/article/details/104057450