题意:已知一些农田的灌溉方式,题中给出m*n大小的农田,求最少设置多少水源,可以把农田全部灌溉。。
思路:DFS,跟做过的那个“水坑数”差不多,但是“灌溉方式”和深搜条件不好把握。。
int pipe[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}};这样代表灌溉方式:例如:
A的灌溉方式 1,0,1,0 代表了农田 上下左右的状态。
DFS条件:例如想要向上深搜,只有这块农田的上状态是1,同时上面的农田的下状态是1,满足这两个条件才可以深搜。。
#include<iostream>
using namespace std;
char map[55][55];
int vis[55][55];
int m,n;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//在矩阵里的上下左右移动
int pipe[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 dfs(int a,int b)
{
int ta,tb;
vis[a][b]=1;
char ch=map[a][b];//把该位置的农田字母号记下来
//printf("a=%d,b=%d",a,b);
for(int i=0;i<4;i++)
{
ta=a+dir[i][0];
tb=b+dir[i][1];
if(!vis[ta][tb]&&ta>=0&&ta<m&&tb>=0&&tb<n)
{
if(i==0||i==1)//向上或向下走
{
if(pipe[ch-'A'][i]&&pipe[map[ta][tb]-'A'][!i])//深搜条件(i=0代表上状态的话,!i=1也就是上面农田的下状态)
{
vis[ta][tb]=1;
dfs(ta,tb);
}
}
else if(i==2)//向左走
{
if(pipe[ch-'A'][i]&&pipe[map[ta][tb]-'A'][i+1])
{
vis[ta][tb]=1;
dfs(ta,tb);
}
}
else if(i==3)//向右走
{
if(pipe[ch-'A'][i]&&pipe[map[ta][tb]-'A'][i-1])
{
vis[ta][tb]=1;
dfs(ta,tb);
}
}
}
}
return 0;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==-1&&n==-1) break;
int step=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>map[i][j];
getchar();
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(!vis[i][j])
{
dfs(i,j);//搜到不能搜了,也就是没有互相连通的了,就返回,同时水源数加一
step++;
}
}
printf("%d\n",step);
}
}