D - Farm Irrigation HDU - 1198(bfs、dfs连通块、并查集)

思路

在这里插入图片描述

  • 题意
  1. 给我们一个n*m的农田,每块小块农田的的地下,都有一个如上图所示的水管,某块小农田可以与相邻的小农田连通,如果这两个小农田的 管道可以拼接到一起,问我们 这个图中的 “连通块” 有几个
  • 分析
  1. 这一题 可以用 dfs去递归搜索连通块的数量、也可以用bfs去搜索,最后统计一下dfs、bfs调用的次数就是答案;也可以用并查集 不断合并集合,最终判读 集合的数量就是答案,
  2. 这题 要注意的是怎么判读:当前的某个农田x与,水平/竖直方向的农田可以连通?
  3. 我们讨论:x与相邻水平方向的农田的连通的的判断条件,我们设x左边的那块农田为y,如果x与y连通,要求:x在水平靠左方向左方向上有管道,而且还要求y在水平向右的方向上也有管道,这样就可以确定x与y判断连通,在实际的代码上就是用一个二维数mv[][]组预处理11种管道在四个方向上是否有指向的水管接头,通过x、y农田中的管道类型去访问mv从而获得x、y农田水管接头的方向

最后给自己提醒一下:给农田求编号的时候 乘的是列数

代码

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <unordered_map>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
#define pr printf
using namespace std;

const int mxn = 55;
int n, m;
int mz[mxn][mxn];
int mv[15][4];
int a[mxn * mxn];
void get_mv()
{
    mv[0][0] = 1, mv[0][1] = 0, mv[0][2] = 1, mv[0][3] = 0;
    mv[1][0] = 1, mv[1][1] = 0, mv[1][2] = 0, mv[1][3] = 1;
    mv[2][0] = 0, mv[2][1] = 1, mv[2][2] = 1, mv[2][3] = 0;
    mv[3][0] = 0, mv[3][1] = 1, mv[3][2] = 0, mv[3][3] = 1;
    mv[4][0] = 1, mv[4][1] = 1, mv[4][2] = 0, mv[4][3] = 0;
    mv[5][0] = 0, mv[5][1] = 0, mv[5][2] = 1, mv[5][3] = 1;
    mv[6][0] = 1, mv[6][1] = 0, mv[6][2] = 1, mv[6][3] = 1;
    mv[7][0] = 1, mv[7][1] = 1, mv[7][2] = 1, mv[7][3] = 0;
    mv[8][0] = 0, mv[8][1] = 1, mv[8][2] = 1, mv[8][3] = 1;
    mv[9][0] = 1, mv[9][1] = 1, mv[9][2] = 0, mv[9][3] = 1;
    mv[10][0] = 1, mv[10][1] = 1, mv[10][2] = 1, mv[10][3] = 1;
}
void init(int n, int m)
{
    for_(i, 0, n * m)
        a[i] = i;
}

int find(int x)
{
    if(a[x] == x)
        return x;
    return a[x] = find(a[x]);  
}

void Union(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx != fy)
        a[fx] = fy;
}



int main()
{
    /* fre(); */
    get_mv();
    while(sc("%d %d ", &n, &m) && n >= 0 && m >= 0)
    {
        init(n, m);
        char ch;
        for_(i, 0, n - 1)
            for_(j, 0, m - 1)
            sc("%c ", &ch), mz[i][j] = ch - 'A';

        for_(i, 0, n - 1)
            for_(j, 0, m - 1)
            {
                int x = i * m + j, y, t;            //注意这里 乘的是 m ---列数啊!!!!
                int num = mz[i][j];
                t = mz[i - 1][j];
                if(i - 1 >= 0 && mv[num][0] && mv[t][1])
                {
                    y = (i - 1) * m + j;//注意这里 乘的是 m ---列数啊!!!!
                    Union(x, y);
                }
                t = mz[i][j - 1];
                if(j - 1 >= 0 && mv[num][2] && mv[t][3])
                {
                    y = i * m + j - 1;//注意这里 乘的是 m ---列数啊!!!!
                    Union(x, y);
                }
            }
        int ans = 0;
        for_(i, 0, n - 1)
            for_(j, 0, m - 1)
            {
                int num = i * m + j; //注意这里 乘的是 m ---列数啊!!!!
                if(a[num] == num)
                    ans ++;
            }
        printf("%d\n", ans);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34261446/article/details/107453892