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

打印 上一主题 下一主题

主题 1974|帖子 1974|积分 5922

图论

题目

99. 岛屿数量
使用 DFS 实现方法
判断岛屿方法
1. 遍历图,若遍历到了陆地 grid[j] = 1 而且陆地没有被访问,在这个陆地的基础上进行 DFS 方法,大概是 BFS 方法
2. 对陆地进行 DFS 的时间时刻注意以访问的元素添加访问标记

  1. // DFS方法1
  2. #include <iostream>
  3. #include <vector>
  4. int dir[4][2] = {0,1,1,0,-1,0,0,-1};
  5. void dfs(std::vector<std::vector<int>>& grid, std::vector<std::vector<bool>>& vis, int x, int y) {
  6.     // 从四个方向进行搜索
  7.     for (int i = 0; i < 4; ++i) {
  8.         int nexti = x + dir[i][0];
  9.         int nextj = y + dir[i][1];
  10.         // 边界情况判定
  11.         if (nexti < 0 || nexti >= grid.size()
  12.          || nextj < 0 || nextj >= grid[0].size()) continue;
  13.         // 访问情况判定
  14.         if (!vis[nexti][nextj] && grid[nexti][nextj] == 1) {
  15.             // 时刻注意访问标记
  16.             vis[nexti][nextj] = true;
  17.             dfs(grid, vis, nexti, nextj);
  18.         }
  19.     }
  20. }
  21. int main() {
  22.     // 输入处理
  23.     int n, m, res = 0;
  24.     std::cin >> n >> m;
  25.     std::vector<std::vector<int>> grid(n, std::vector<int>(m, 0));
  26.     std::vector<std::vector<bool>> vis(n, std::vector<bool>(m, false));
  27.     for (int i = 0; i < n; ++i) {
  28.         for (int j = 0; j < m; ++j) {
  29.             std::cin >> grid[i][j];
  30.         }
  31.     }
  32.     // 遍历网格进行DFS操作
  33.     for (int i = 0; i < n; ++i) {
  34.         for (int j = 0; j < m; ++j) {
  35.             // 访问到新陆地对该陆地进行遍历
  36.             if (grid[i][j] == 1 && !vis[i][j]) {
  37.                 res++; // 记录新大陆
  38.                 vis[i][j] = true;
  39.                 dfs(grid, vis, i, j);
  40.             }
  41.         }
  42.     }
  43.     // 输出处理
  44.     std::cout << res << std::endl;
  45. }
  46. // dfs 三部曲写法
  47. #include <iostream>
  48. #include <vector>
  49. using namespace std;
  50. int dir[4][2] = {0,-1,-1,0,1,0,0,1}; // 逆时针顺序
  51. // 第一步参数与返回值
  52. void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
  53.     // 第二部 终止条件
  54.     if (vis[x][y] || grid[x][y] == 0) return;
  55.     // 第三部 单层递归逻辑
  56.     vis[x][y] = true;
  57.     for (int i = 0; i < 4; ++i) {
  58.         int nextX = x + dir[i][0];
  59.         int nextY = y + dir[i][1];
  60.         if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
  61.         dfs(grid, vis, nextX, nextY);
  62.     }
  63. }
  64. int main() {
  65.     int n, m, res = 0;
  66.     cin >> n >> m;
  67.     vector<vector<int>> grid(n, vector<int>(m, 0));
  68.     vector<vector<bool>> vis(n, vector<bool>(m, false));
  69.     for (int i = 0; i < n; ++i) {
  70.         for (int j = 0; j < m; ++j) {
  71.             cin >> grid[i][j];
  72.         }
  73.     }
  74.     for (int i = 0; i < n; ++i) {
  75.         for (int j = 0; j < m; ++j) {
  76.             if (!vis[i][j] && grid[i][j] == 1) {
  77.                 res++;
  78.                 dfs(grid, vis, i, j);
  79.             }
  80.         }
  81.     }
  82.     cout << res << endl;
  83. }
复制代码
使用广度优先搜刮方法
主函数部分稳固,调用酿成广度优先搜刮
广度优先搜刮包管入队列的时间就对数据做标记为访问
如果在取出队列时间标记会导致大量重复元素入队!
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. using namespace std;
  5. int dir[4][2] = {0,-1,-1,0,1,0,0,1};
  6. void bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
  7.     // 创建队列存储下标
  8.     queue<pair<int, int>> que;
  9.     // 保证入队的时候就标记访问防止重复访问
  10.     que.push(make_pair(x, y));
  11.     while (!que.empty()) {
  12.         pair<int, int> cur = que.front();
  13.         que.pop();
  14.         for (int i = 0; i < 4; ++i) {
  15.             int nextX = cur.first + dir[i][0];
  16.             int nextY = cur.second + dir[i][1];
  17.             if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
  18.             if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
  19.                 que.push({nextX, nextY});
  20.                 vis[nextX][nextY] = true; // 入队即标记防止重复
  21.             }
  22.         }
  23.     }
  24. }
  25. int main() {
  26.     int n, m, res = 0;
  27.     cin >> n >> m;
  28.     vector<vector<int>> grid(n, vector<int>(m, 0));
  29.     vector<vector<bool>> vis(n, vector<bool>(m, false));
  30.     for (int i = 0; i < n; ++i) {
  31.         for (int j = 0; j < m; ++j) {
  32.             cin >> grid[i][j];
  33.         }
  34.     }
  35.     for (int i = 0; i < n; ++i) {
  36.         for (int j = 0; j < m; ++j) {
  37.             if (!vis[i][j] && grid[i][j] == 1) {
  38.                 res++;
  39.                 bfs(grid, vis, i, j);
  40.             }
  41.         }
  42.     }
  43.     cout << res << endl;
  44. }
复制代码
100. 岛屿的最大面积
岛屿最大面积,给出广度优先搜刮,深度优先搜刮(A 和 B)
深度优先 B广度优先在函数外初始化记录,深度优先 A 在函数内初始化记录
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <algorithm>
  5. using namespace std;
  6. int tmp = 0;
  7. int dir[4][2] = {0,-1,-1,0,1,0,0,1};
  8. int bfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
  9.     tmp = 1;
  10.     queue<pair<int, int>> que;
  11.     que.push(make_pair(x, y));
  12.     vis[x][y] = true;
  13.     while (!que.empty()) {
  14.         pair<int, int> cur = que.front();
  15.         que.pop();
  16.         for (int i = 0; i < 4; ++i) {
  17.             int nextX = cur.first + dir[i][0];
  18.             int nextY = cur.second + dir[i][1];
  19.             if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
  20.             if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
  21.                 tmp++;
  22.                 que.push({nextX, nextY});
  23.                 vis[nextX][nextY] = true;
  24.             }
  25.         }
  26.     }
  27.     return tmp;
  28. }
  29. void dfs(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
  30.     // 1 fin
  31.     if (vis[x][y] || grid[x][y] == 0) return;
  32.     vis[x][y] = true;
  33.     tmp++;
  34.     for (int i = 0; i < 4; ++i) {
  35.         int nextX = x + dir[i][0];
  36.         int nextY = y + dir[i][1];
  37.         if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid[0].size()) continue;
  38.         dfs(grid, vis, nextX, nextY);
  39.     }
  40. }
  41. void dfs2(vector<vector<int>>& grid, vector<vector<bool>>& vis, int x, int y) {
  42.     // 2
  43.     for (int i = 0; i < 4; ++i) {
  44.         int nextX = x + dir[i][0];
  45.         int nextY = y + dir[i][1];
  46.         if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY > grid[0].size()) continue;
  47.         if (!vis[nextX][nextY] && grid[nextX][nextY] == 1) {
  48.             tmp++;
  49.             vis[nextX][nextY] = true;
  50.             dfs2(grid, vis, nextX, nextY);
  51.         }
  52.     }
  53. }
  54. int main(){
  55.     int n, m, res = 0, maxV = 0;
  56.     cin >> n >> m;
  57.     vector<vector<int>> grid(n, vector<int>(m, 0));
  58.     vector<vector<bool>> vis(n, vector<bool>(m, false));
  59.     for (int i = 0; i < n; ++i) {
  60.         for (int j = 0; j < m; ++j) {
  61.             cin >> grid[i][j];
  62.         }
  63.     }
  64.     for (int i = 0; i < n; ++i) {
  65.         for (int j = 0; j < m; ++j) {
  66.             if (!vis[i][j] && grid[i][j] == 1) {
  67.                 res++;
  68.                 // 深度优先 1
  69.                 // tmp = 0; // 因为dfs内首先计算tmp
  70.                 // dfs(grid, vis, i, j);
  71.                 // maxV = max(maxV, tmp);
  72.                 // 深度优先 2
  73.                 tmp = 1; // dfs需要初始
  74.                 vis[i][j] = true;
  75.                 dfs2(grid, vis, i, j);
  76.                 maxV = max(maxV, tmp);
  77.                 // 广度优先
  78.                 // maxV = max(maxV, bfs(grid, vis, i, j));
  79.             }
  80.         }
  81.     }
  82.     // cout << "res" << res << endl;
  83.     cout << maxV << endl;
  84.     return 0;
  85. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表