HDU 1198 Farm Irrigation

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1198



题目:

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.

HDU 1198 Farm Irrigation
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

HDU 1198 Farm Irrigation
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


题目大意:

有A~K共9种类型的田地,每种田上面的水渠是不同的(它们连接的出口不同)。然后由这些类型的田组成一个n*m大小的更大的田,由于相邻两个田地的水渠可能可以相通(有接口),所以只要相通的那些田地只需要一个水源就可以了。求最少需要多少个水源。


分析:

可用bfs,dfs做,不过用并查集更方便点。 用并查集只需要判断一个田周围的四个田,如果有接口,那么就把这两个田合并成一棵树,最后判断几棵树即可。


代码:

// 并查集
#include<cstdio>
#include<cstring>
#define N 55
int n,m,f[N*N],rank[N*N];
int map[55][55];
// 左,上,右,下
int dir[4][2]={{0,-1},{-1,0},{0,1},{1,0}};

// 田的类型。 按顺序上,右,下,左,有出口的是1,无的是0
int farm[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}
};

inline void initSet(){
    for(int i=0; i<N*N; ++i)
        f[i]=i,rank[i]=0;
}
int find(int x){
    int i,j=x;
    while(j!=f[j]) j=f[j];
    while(x!=j){
        i=f[x];
        f[x]=j;
        x=i;
    }
    return j;
}
void Union(int x,int y){
    int a=find(x), b=find(y);
    if(a==b)return ;
    if(rank[a]>rank[b])
        f[b]=a;
    else{
        if(rank[a]==rank[b])
            ++rank[b];
        f[a]=b;
    }
}


int main(){
    char ch;
    while(scanf("%d%d%*c",&n,&m)&&n>=1&&m>=1){
        for(int i=0; i<n; ++i){
            for(int j=0; j<m; ++j){
                scanf("%c",&ch);
                map[i][j]=ch-'A';
            }
            getchar();
        }
        initSet();
        for(int i=0; i<n; ++i){
            for(int j=0; j<m; ++j){
                for(int k=0; k<4; ++k){
                    int dx=i+dir[k][0],dy=j+dir[k][1];
                    if(dx<0||dx>=n||dy<0||dy>=m)continue;
                    if(k==0){ // 左
                        if(farm[map[dx][dy]][1]&&farm[map[i][j]][3]){
                            Union(dx*m+dy, i*m+j);
                        }
                    }
                    else if(k==1){ // 上
                        if(farm[map[dx][dy]][2]&&farm[map[i][j]][0]){
                            Union(dx*m+dy, i*m+j);
                        }
                    }
                    else if(k==2){ // 右
                        if(farm[map[dx][dy]][3]&&farm[map[i][j]][1]){
                            Union(dx*m+dy, i*m+j);
                        }
                    }
                    else if(k==3){ // 下
                        if(farm[map[dx][dy]][0]&&farm[map[i][j]][2]){
                            Union(dx*m+dy, i*m+j);
                        }
                    }
                } 
            }
        }
        int cnt=0;
        for(int i=0; i<n*m; ++i)
            if(f[i]==i) 
                ++cnt;
        printf("%d\n", cnt);
    }
    return 0;
}


—— 生命的意义,在于赋予它意义。

原创http://blog.csdn.net/shuangde800By D_Double (转载请标明)


你可能感兴趣的:(HDU)