01聯通塊求解——bfs

##1.問題描述:
聯通性問題1.png
聯通性問題2.png

##2.算法分析:
其實這道題目就是一個讓我們求出一共有多少個聯通塊問題;
首先我們要理解怎樣纔算是聯通塊,比如單個的1四周被0包圍,算作聯通塊,或者1連着的1兩個1算作一個聯通塊,只要1的上下左右任一個方向存在1都算作一個聯通塊,比如樣例一:
聯通快問題3.png
聯通塊問題4.png
大概就這麼個意思。
那麼我們該怎麼做了,比較容易就想到搜索了,我們枚舉每一個位置的元素,如果爲0,則跳過,如果爲1開始搜索。(基本做法)
我們搜素就使用bfs來向四周掃描(前提不能出界),如果相鄰的位置繼續向四周擴散,直到整個’1’的塊訪問完,每次訪問完都標記爲訪問過,然後每次訪問check一下座標是否合法即可。
check函數常用寫法:

bool check(int x, int y) {
    if (x >= n || x < 0 || y >= m || y < 0) return false; //越界判斷
    if (mp[x][y] == '0' || vis[x][y]) return false;   //判斷是否訪問過或者不能訪問的
    return true;
}

然後完成基本的bfs函數即可。

##3.ac代碼:

#include <bits/stdc++.h>
using namespace std;
 
int n, m;
char mp[55][55];
bool vis[55][55];
int dir[4][2] = {{0,1},{0, -1}, {1, 0}, {-1, 0}};
struct node{
    int x, y;
    node(int xx, int yy) {
        x = xx;
        y = yy;
    }
};
 
queue<node> q;
 
bool check(int x, int y) {
    if (x >= n || x < 0 || y >= m || y < 0) return false;
    if (mp[x][y] == '0' || vis[x][y]) return false;
    return true;
}
 
void bfs(int x, int y) {
    q.push(node(x, y));
    vis[x][y] = true;
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int tx = now.x + dir[i][0];
            int ty = now.y + dir[i][1];
            if (check(tx, ty)) {
                q.push(node(tx, ty));
                vis[tx][ty] = true;
            }
        }
    }
}
 
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(vis, false, sizeof(vis));
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++) {
            scanf("%s", mp[i]);
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mp[i][j] == '1' && vis[i][j] == false) {
                    ans++;
                    bfs(i, j);
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

題目鏈接:相聚

歡迎關注:ly’s Blog

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章