hud1198 Farm Irrigation

来源:互联网 发布:户型改造软件 编辑:程序博客网 时间:2024/06/16 08:23

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. Waterpipes are placed in these squares. Different square has a different type ofpipe. There are 11 types of pipes, which is marked from A to K, as Figure 1shows.

 

Figure 1

 

Benny has a map of his farm, which is anarray 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 centerof 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 isirrigated and will have a good harvest in autumn.

 

Now Benny wants to know at least how manywellsprings should be found to have the whole farm land irrigated. Can you helphim?

 

Note: In the above example, at least 3wellsprings are needed, as those red points in Figure 2 show.

 

 

Input

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

 

Output

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

 

Sample Input

2 2

DK

HF

 

3 3

ADC

FJK

IHE

 

-1 -1

 

 

Sample Output

2

3

 

题解:

这道题用的是并查集,每个点都记录为一个节点,同时需要记录该点的上下左右能不能联通。初始化每个节点,一开始每个节点的父结点都是自己。然后就是搜索,每个点都需要搜索上下左右四个位置,如果能够连通的话,就进行结合union()。当每个点都查过以后,进行搜索,查找有多少个父结点。父结点的个数就是需要多少的水源。

 

 

 

源代码:

#include <iostream>

#include <string>

#include <cstring>

using namespace std;

 

#define MAXINT 110

int link[MAXINT][MAXINT][4];

int dir[4][2] ={{0,-1},{0,1},{-1,0},{1,0}};

 

struct nd

{

       intrank;

       intparent;

}tree[MAXINT*MAXINT];

 

void init(int k)

{

       for(inti = 0;i < k;i++)

       {

              tree[i].parent= i;

              tree[i].rank= 0;

       }

}

 

int find_parent(int num)

{

       if(tree[num].parent== num)

              returnnum;

       elsereturn tree[num].parent = find_parent(tree[num].parent);

}

 

void UNION(inta,int b)

{

       a= find_parent(a);

       b= find_parent(b);

 

       if(a== b)

              return;

       else

       {

              if(tree[a].rank> tree[b].rank)

              {

                     tree[b].parent = a;

              }

              else

              {

                     if(tree[a].rank== tree[b].rank)

                            tree[b].rank++;

                     tree[a].parent= b;

              }

       }

}

 

int main()

{

       intn,m;

 

       while(cin>> n >> m)

       {

              if(n< 0&& m < 0)

                     break;

              init(n*m);

              charch;

              for(inti = 0;i < n;i++)

                     for(intj = 0;j < m;j++)

                     {

                            cin>> ch;

 

                            switch(ch)

                            {

                            case'A': link[i][j][0] = 1;link[i][j][1] = 0;

                                            link[i][j][2] = 1;link[i][j][3] = 0;break;

                            case'B': link[i][j][0] = 0;link[i][j][1] = 1;

                                            link[i][j][2] = 1;link[i][j][3] = 0;break;

                         case 'C': link[i][j][0] = 1;link[i][j][1] =0;

                                            link[i][j][2] = 0;link[i][j][3] = 1;break;

                            case'D': link[i][j][0] = 0;link[i][j][1] = 1;

                                            link[i][j][2] = 0;link[i][j][3] = 1;break;

                            case'E': link[i][j][0] = 0;link[i][j][1] = 0;

                                            link[i][j][2] = 1;link[i][j][3] = 1;break;

                         case 'F': link[i][j][0] = 1;link[i][j][1] =1;

                                            link[i][j][2] = 0;link[i][j][3] = 0;break;

                         case 'G': link[i][j][0] = 1;link[i][j][1] =1;

                                            link[i][j][2] = 1;link[i][j][3] = 0;break;

                         case 'H': link[i][j][0] = 1;link[i][j][1] =0;

                                            link[i][j][2] = 1;link[i][j][3] = 1;break;

                         case 'I': link[i][j][0] = 1;link[i][j][1] =1;

                                            link[i][j][2] = 0;link[i][j][3] = 1;break;

                            case'J': link[i][j][0] = 0;link[i][j][1] = 1;

                                            link[i][j][2] = 1;link[i][j][3] = 1;break;

                         case 'K': link[i][j][0] = 1;link[i][j][1] =1;

                                            link[i][j][2] = 1;link[i][j][3] = 1;break;

                            }

                     }

             

              for(inti = 0;i < n;i++)

                     for(intk = 0;k < m;k++)

                     {

                            for(intj = 0;j < 4;j++)

                            {

                                   intx = i + dir[j][0];

                                   inty = k + dir[j][1];

 

                                   if(x< 0 || y < 0||x >= n || y >= m)

                                          continue;

                                   else

                                   {

                                          switch(j)

                                          {

                                          case0:if(link[i][k][j]&&link[x][y][1])

                                                           UNION(i*m+k,x*m+y);

                                                    break;

                                          case1:if(link[i][k][j]&&link[x][y][0])

                                                           UNION(i*m+k,x*m+y);

                                                    break;

                                          case2:if(link[i][k][j]&&link[x][y][3])

                                                           UNION(i*m+k,x*m+y);

                                                    break;

                                          case3:if(link[i][k][j]&&link[x][y][2])

                                                           UNION(i*m+k,x*m+y);

                                                    break;

                                          }

                                   }

                            }

                     }

 

              intnum = 0;

              for(inti = 0;i < n*m;i++)

              {

                     if(tree[i].parent== i)

                            num++;

              }

 

              cout<< num << endl;

       }

       return0;

}