代码随想录算法训练营第五十一天|图论part2
99.岛屿数量 深搜
题目链接:99. 岛屿数量
文章讲解:代码随想录
思路:
先将岛屿数据存储到二维矩阵,遍历二维矩阵,遇到1,则统计数量+1,然后将该岛屿四个方向的岛屿都标为已访问。
记得处理边界情况
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void dfs(vector<vector<int>>graph,vector<vector<bool>>&isvisited,int x,int y){for(int i=0;i<4;i++){//考虑四个方向int nextx=x+dir[i][0];int nexty=y+dir[i][1];//边界检查if(nextx<1||nextx>=graph.size()||nexty<1||nexty>=graph[0].size())continue;if(graph[nextx][nexty]==1&&!isvisited[nextx][nexty]){isvisited[nextx][nexty]=true;dfs(graph,isvisited,nextx,nexty);}}
}int main(){int n,m,x;cin>>n>>m;vector<vector<int>>graph(n+1,vector<int>(m+1,1));vector<vector<bool>>isvisited(n+1,vector<bool>(m+1,false));for(int i=1;i<=n;i++){ //用二维矩阵存储图for(int j=1;j<=m;j++){cin>>x;graph[i][j]=x;}}int result=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(!isvisited[i][j]&&graph[i][j]){isvisited[i][j]=true;result++;dfs(graph,isvisited,i,j); //将相连的陆地标记为已访问}}}cout<<result<<endl;
}
99.岛屿数量 广搜
题目链接:99. 岛屿数量
文章讲解:代码随想录
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void bfs(vector<vector<int>>graph,vector<vector<bool>>&isvisited,int x,int y){queue<pair<int,int>>mq;mq.push({x,y}); //注意pair的用法while(!mq.empty()){auto current = mq.front(); // ✅ 取出当前节点!!!!!!!!!!mq.pop();int curx = current.first;int cury = current.second;for(int i=0;i<4;i++){//考虑四个方向int nextx=curx+dir[i][0];int nexty=cury+dir[i][1];if(nextx<1||nextx>=graph.size()||nexty<1||nexty>=graph[0].size())continue;if(graph[nextx][nexty]==1&&!isvisited[nextx][nexty]){isvisited[nextx][nexty]=true;mq.push({nextx,nexty});}}}}int main(){int n,m,x;cin>>n>>m;vector<vector<int>>graph(n+1,vector<int>(m+1,1));vector<vector<bool>>isvisited(n+1,vector<bool>(m+1,false));for(int i=1;i<=n;i++){ //用二维矩阵存储图for(int j=1;j<=m;j++){cin>>x;graph[i][j]=x;}}int result=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(!isvisited[i][j]&&graph[i][j]){isvisited[i][j]=true;result++;bfs(graph,isvisited,i,j); //将相连的陆地标记为已访问}}}cout<<result<<endl;
}
广度优先搜索遍历:
新建一个队列,当前节点入队,
while队列不为空,获取队首节点,处理当前节点逻辑,符合条件的入队。
100.岛屿的最大面积
题目链接:100. 岛屿的最大面积
文章讲解:代码随想录
思路:
基本解法与上题一样
找到一个岛屿 然后用广度或者深度优先搜索去遍历周围相连的岛屿,每有一个相连,面积加1
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
//深度优先
void dfs(vector<vector<int>>graph,vector<vector<bool>>&visited,int &area,int x, int y){for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=graph.size()||nexty<0||nexty>graph[0].size()) continue;if(graph[nextx][nexty]==1&&!visited[nextx][nexty]){visited[nextx][nexty]=true;area++;dfs(graph,visited,area,nextx,nexty);}}
}
//广度优先
void bfs(vector<vector<int>>graph,vector<vector<bool>>&visited,int &area,int x, int y){queue<pair<int,int>>mq; mq.push({x,y}); //当前节点入队while(!mq.empty()){auto curnode=mq.front(); //队首节点出队mq.pop();int curx=curnode.first;int cury=curnode.second;for(int i=0;i<4;i++){ //处理当前节点有联系的int nextx=curx+dir[i][0];int nexty=cury+dir[i][1];if(nextx<0||nextx>=graph.size()||nexty<0||nexty>graph[0].size()) continue;if(graph[nextx][nexty]==1&&!visited[nextx][nexty]){visited[nextx][nexty]=true;area++;mq.push({nextx,nexty}); //有联系的入队}}}
}int main(){int n,m;cin>>n>>m;vector<vector<int>>graph(n+1,vector<int>(m+1,0));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>graph[i][j];}}vector<vector<bool>>visited(n+1,vector<bool>(m+1,false));int maxArea=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(graph[i][j]==1&&!visited[i][j]){int area=1;visited[i][j]=true;bfs(graph,visited,area,i,j);// dfs(graph,visited,area,i,j);maxArea=max(maxArea,area);}}}cout<<maxArea<<endl;
}