代码随想录算法训练营 Day51 图论Ⅱ岛屿问题Ⅰ

图论

题目

99. 岛屿数量

使用 DFS 实现方法

判断岛屿方法

  1. 遍历图,若遍历到了陆地 grid[i][j] = 1 并且陆地没有被访问,在这个陆地的基础上进行 DFS 方法,或者是 BFS 方法

  2. 对陆地进行 DFS 的时候时刻注意以访问的元素添加访问标记

cpp 复制代码
// DFS方法1
#include <iostream>
#include <vector>

int dir[4][2] = {0,1,1,0,-1,0,0,-1};
void dfs(std::vector<std::vector<int>>& grid, std::vector<std::vector<bool>>& vis, int x, int y) {
    // 从四个方向进行搜索
    for (int i = 0; i < 4; ++i) {
        int nexti = x + dir[i][0];
        int nextj = y + dir[i][1];
        // 边界情况判定
        if (nexti < 0 || nexti >= grid.size()
         || nextj < 0 || nextj >= grid[0].size()) continue;
        // 访问情况判定
        if (!vis[nexti][nextj] && grid[nexti][nextj] == 1) {
            // 时刻注意访问标记
            vis[nexti][nextj] = true;
            dfs(grid, vis, nexti, nextj);
        }
    }
}

int main() {
    // 输入处理
    int n, m, res = 0;
    std::cin >> n >> m;
    std::vector<std::vector<int>> grid(n, std::vector<int>(m, 0));
    std::vector<std::vector<bool>> vis(n, std::vector<bool>(m, false));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            std::cin >> grid[i][j];
        }
    }
    // 遍历网格进行DFS操作
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            // 访问到新陆地对该陆地进行遍历
            if (grid[i][j] == 1 && !vis[i][j]) {
                res++; // 记录新大陆
                vis[i][j] = true;
                dfs(grid, vis, i, j);
            }
        }
    }

    // 输出处理
    std::cout << res << std::endl;
}


// dfs 三部曲写法
#include <iostream>
#include <vector>
using namespace std;

int dir[4][2] = {0,-1,-1,0,1,0,0,1}; // 逆时针顺序
// 第一步参数与返回值
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 第二部 终止条件
    if (vis[x][y] || grid[x][y] == 0) return;
    // 第三部 单层递归逻辑
    vis[x][y] = true;
    for (int i = 0; i < 4; ++i) {
        int nextX = x + dir[i][0];
        int nextY = y + dir[i][1];
        if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
        dfs(grid, vis, nextX, nextY);
    }
}

int main() {
    int n, m, res = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(n, vector<bool>(m, false));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> grid[i][j];
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (!vis[i][j] && grid[i][j] == 1) {
                res++;
                dfs(grid, vis, i, j);
            }
        }
    }

    cout << res << endl;
}

使用广度优先搜索方法

主函数部分不变,调用变成广度优先搜索

广度优先搜索保证入队列的时候就对数据做标记为访问

如果在取出队列时候标记会导致大量重复元素入队!

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int dir[4][2] = {0,-1,-1,0,1,0,0,1};
void bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 创建队列存储下标
    queue<pair<int, int>> que;
    // 保证入队的时候就标记访问防止重复访问
    que.push(make_pair(x, y));
    while (!que.empty()) {
        pair<int, int> cur = que.front();
        que.pop();
        for (int i = 0; i < 4; ++i) {
            int nextX = cur.first + dir[i][0];
            int nextY = cur.second + dir[i][1];
            if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
            if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
                que.push({nextX, nextY});
                vis[nextX][nextY] = true; // 入队即标记防止重复
            }
        }
    }
}

int main() {
    int n, m, res = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(n, vector<bool>(m, false));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> grid[i][j];
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (!vis[i][j] && grid[i][j] == 1) {
                res++;
                bfs(grid, vis, i, j);
            }
        }
    }

    cout << res << endl;
}

100. 岛屿的最大面积

岛屿最大面积,给出广度优先搜索,深度优先搜索(A 和 B)

深度优先 B广度优先在函数外初始化记录,深度优先 A 在函数内初始化记录

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

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

int bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    tmp = 1;
    queue<pair<int, int>> que;
    que.push(make_pair(x, y));
    vis[x][y] = true;
    while (!que.empty()) {
        pair<int, int> cur = que.front();
        que.pop();
        for (int i = 0; i < 4; ++i) {
            int nextX = cur.first + dir[i][0];
            int nextY = cur.second + dir[i][1];
            if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
            if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
                tmp++;
                que.push({nextX, nextY});
                vis[nextX][nextY] = true;
            }
        }
    }
    return tmp;
}

void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 1 fin
    if (vis[x][y] || grid[x][y] == 0) return;
    vis[x][y] = true;
    tmp++;
    for (int i = 0; i < 4; ++i) {
        int nextX = x + dir[i][0];
        int nextY = y + dir[i][1];
        if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
        dfs(grid, vis, nextX, nextY);
    }
}

void dfs2(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
    // 2
    for (int i = 0; i < 4; ++i) {
        int nextX = x + dir[i][0];
        int nextY = y + dir[i][1];
        if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY > grid[0].size()) continue;
        if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
            tmp++;
            vis[nextX][nextY] = true;
            dfs2(grid, vis, nextX, nextY);
        }
    }
}


int main(){
    int n, m, res = 0, maxV = 0;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    vector<vector<bool>> vis(n, vector<bool>(m, false));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> grid[i][j];
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (!vis[i][j] && grid[i][j] == 1) {
                res++;
                // 深度优先 1
                // tmp = 0; // 因为dfs内首先计算tmp
                // dfs(grid, vis, i, j);
                // maxV = max(maxV, tmp);
                // 深度优先 2
                tmp = 1; // dfs需要初始
                vis[i][j] = true;
                dfs2(grid, vis, i, j);
                maxV = max(maxV, tmp);
                // 广度优先
                // maxV = max(maxV, bfs(grid, vis, i, j));
            }
        }
    }
    // cout << "res" << res << endl;
    cout << maxV << endl;
    return 0;
}
相关推荐
三维重建-光栅投影1 小时前
VS中将cuda项目编译为DLL并调用
算法
课堂剪切板3 小时前
ch03 部分题目思路
算法
山登绝顶我为峰 3(^v^)34 小时前
如何录制带备注的演示文稿(LaTex Beamer + Pympress)
c++·线性代数·算法·计算机·密码学·音视频·latex
Two_brushes.5 小时前
【算法】宽度优先遍历BFS
算法·leetcode·哈希算法·宽度优先
森焱森7 小时前
水下航行器外形分类详解
c语言·单片机·算法·架构·无人机
QuantumStack9 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
写个博客10 小时前
暑假算法日记第一天
算法
绿皮的猪猪侠10 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
hie9889411 小时前
MATLAB锂离子电池伪二维(P2D)模型实现
人工智能·算法·matlab
杰克尼11 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表