hdu 1198 Farm Irrigation

来源:互联网 发布:淘宝定价规则 编辑:程序博客网 时间:2024/06/14 17:26

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

较为隐蔽的并查集题目,但是分析发现还是统计集合个数的问题,需要注意的是集合的合并是有条件的,满足条件的合并,不满足的不合并。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int MAX = 500;int n,m,cnt,father[MAX*MAX],hash[MAX][MAX];int d[12][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 Move[][2] = {{-1,0},{0,1},{1,0},{0,-1}};//方向数组char map[MAX][MAX];bool II(int x, int y){    if(x < 0 || x >= n || y < 0 || y >= m)        return false;    return true;}void Init(){    for(int i=0; i<=n*m; i++)        father[i] = i;}int Find(int x){    if(x != father[x])        father[x] = Find(father[x]);    return father[x];}void Union(int x, int y){    int xx = Find(x), yy = Find(y);    father[yy] = xx;    return;}int main(){    while(scanf("%d%d",&n,&m) == 2){        if(n == -1 && m == -1) break;        Init();        for(int i=0; i<n; i++) cin >> map[i];        for(int i=0; i<n; i++)            for(int j=0; j<m; j++)            hash[i][j] = i*m+j;//哈希的思想给每个结点标号,标号必须不重复        for(int i=0; i<n; i++){            for(int j=0; j<m; j++){                for(int k=0; k<4; k++){                    int dx = i + Move[k][0], dy = j + Move[k][1];                    if(!II(dx, dy)) continue;                    int idu = map[i][j] - 'A', idv = map[dx][dy] - 'A';                    if(k == 0 && d[idu][0] && d[idv][2]) Union(hash[i][j], hash[dx][dy]);                    else if(k == 1 && d[idu][1] && d[idv][3]) Union(hash[i][j], hash[dx][dy]);                    else if(k == 2 && d[idu][2] && d[idv][0]) Union(hash[i][j], hash[dx][dy]);                    else if(k == 3 && d[idu][3] && d[idv][1]) Union(hash[i][j], hash[dx][dy]);                }            }        }        cnt = 0;        for(int i=0; i<n; i++)            for(int j=0; j<m; j++)                if(father[i*m+j] == i*m+j) cnt++;        printf("%d\n",cnt);    }    return 0;}




0 0