转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198
----------------------------------------------------------------------------------------------------------------------------------------------------------
欢迎光临天资小屋:http://user.qzone.qq.com/593830943/main
----------------------------------------------------------------------------------------------------------------------------------------------------------


2 2 DK HF 3 3 ADC FJK IHE -1 -1
2 3
题意:有如上图11种土地块,块中的绿色线条为土地块中修好的水渠,如今一片土地由上述的各种土地块组成。须要浇水,问须要打多少口井。
代码一(dfs):
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define TM 117
//存储11中类型的土地。二维中的0 1 2 3分别代表这样的类型的土地的左上右下  
//为1表示这个方向有接口,为0表示这个方向没有接口 
int a[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},{0,1,0,1},
{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};
int map[TM][TM];
char s[TM][TM];
bool vis[TM][TM];
int n, m, coun;
void dfs(int x, int y)
{
	vis[x][y] = true;
	for(int i = 0; i < 4; i++)
	{
		if(i == 0)//向上查找
		{
			if(a[map[x][y]][0]&&a[map[x-1][y]][2]&&x-1>=0&&!vis[x-1][y])
				dfs(x-1,y);
		}
		else if(i == 1)//向右查找
		{
			if(a[map[x][y]][1]&&a[map[x][y+1]][3]&&y+1<m&&!vis[x][y+1])
				dfs(x,y+1);
		}
		else if(i == 2)//向下查找
		{
			if(a[map[x][y]][2]&&a[map[x+1][y]][0]&&x+1<n&&!vis[x+1][y])
				dfs(x+1,y);
		}
		else if(i == 3)//向左查找
		{
			if(a[map[x][y]][3]&&a[map[x][y-1]][1]&&y-1>=0&&!vis[x][y-1])
				dfs(x,y-1);
		}
	}
	return;
}
void init()//初始化
{
	memset(vis,false,sizeof(vis));
	coun = 0;
}
int main()
{
	int i, j;
	while(cin>>n>>m)
	{
		init();
		if(n==-1 && m==-1)
			break;
		for(i = 0; i < n; i++)
		{
			cin>>s[i];
			for(j = 0; j < m; j++)
			{
				map[i][j] = s[i][j]-'A';
			}
		}
		for(i = 0; i < n; i++)
		{
			for(j = 0; j < m; j++)
			{
				if(!vis[i][j])
				{
					coun++;
					dfs(i,j);
				}
			}
		}
		cout<<coun<<endl;
	}
	return 0;
}#include <iostream>
#include <algorithm>
using namespace std;
#define TM 117
//存储11中类型的土地。二维中的0 1 2 3分别代表这样的类型的土地的左上右下  
//为1表示这个方向有接口。为0表示这个方向没有接口 
int a[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},{0,1,0,1},
{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};
struct p
{
	int f;//记录每块田地水管的分布
	int c;//分别对每块田地编号
}map[TM][TM];
char s[TM][TM];
int father[TM*TM];
int n, m, coun, k;
int find(int x)
{
	return x==father[x]?x:father[x]=find(father[x]);
}
void init()//初始化
{
	for(int i = 0; i <= n*m; i++)
	{
		father[i] = i;
	}
	coun = k = 0;
}
void Union(int x, int y)
{
	int f1 = find(x);
	int f2 = find(y);
	if(f1!=f2)
	{
		father[f2] = f1;
	}
}
void F(int x, int y)
{
	for(int i = 0; i < 4; i++)
	{
		if(i == 0)//向上查找
		{
			if(a[map[x][y].f][0]&&a[map[x-1][y].f][2]&&x-1>=0)
			{
				Union(map[x][y].c,map[x-1][y].c);
			}
		}
		else if(i == 1)//向右查找
		{
			if(a[map[x][y].f][1]&&a[map[x][y+1].f][3]&&y+1<m)
			{
				Union(map[x][y].c,map[x][y+1].c);
			}
		}
		else if(i == 2)//向下查找
		{
			if(a[map[x][y].f][2]&&a[map[x+1][y].f][0]&&x+1<n)
			{
				Union(map[x][y].c,map[x+1][y].c);
			}
		}
		else if(i == 3)//向左查找
		{
			if(a[map[x][y].f][3]&&a[map[x][y-1].f][1]&&y-1>=0)
			{
				Union(map[x][y].c,map[x][y-1].c);
			}
		}
	}
}
int main()
{
	int i, j;
	while(cin>>n>>m)
	{
		init();
		if(n==-1 && m==-1)
			break;
		for(i = 0; i < n; i++)
		{
			cin>>s[i];
			for(j = 0; j < m; j++)
			{
				map[i][j].f = s[i][j]-'A';
				map[i][j].c = k++;
			}
		}
		for(i = 0; i < n; i++)//分别对每块田地查找是否和别的田地的水管联通
		{
			for(j = 0; j < m; j++)
			{
				F(i,j);
			}
		}
		for(i = 0; i < n; i++)
		{
			for(j = 0; j < m; j++)//查找有多少个独立的集合
			{
				if(father[map[i][j].c] == map[i][j].c)
					coun++;
			}
		}
		cout<<coun<<endl;
	}
	return 0;
}
hdu 1198 Farm Irrigation(深搜dfs || 并查集)
原文:http://www.cnblogs.com/lxjshuju/p/7295502.html