图论Day39:孤岛题目

101. 孤岛的总面积

先用dfs遍历四条边界,把与之相连的置为0

再用计算孤岛面积的方法统计总面积

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void dfs(vector<vector<int>>& graph, int x, int y){
    graph[x][y] = 0;
    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){
            dfs(graph, nextx, nexty);
        }
    }
}
void dfs(vector<vector<int>>& graph, int x, int y, vector<vector<bool>>& visited, int &res){
    if(visited[x][y] == true){
        return;
    }
    res++;
    visited[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 >= graph.size() || nexty < 0 || nexty >= graph[0].size()){
            continue;
        }
        if(graph[nextx][nexty] == 1){
            dfs(graph, nextx, nexty, visited, res);
        }
    }
}
int main(){
    int N, M;
    cin >> N >> M;
    vector<vector<int>> graph(N, vector<int>(M, 0));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            cin >> graph[i][j];
        }
    }
    for(int i = 0; i < N; i++){
        if(graph[i][0] == 1){
            dfs(graph, i, 0);
        }
        if(graph[i][M - 1] == 1){
            dfs(graph, i, M - 1);
        }
    }
    for(int j = 0; j < M; j++){
        if(graph[0][j] == 1){
            dfs(graph, 0, j);
        }
        if(graph[N - 1][j] == 1){
            dfs(graph, N - 1, j);
        }
    }
    int res = 0;
    vector<vector<bool>> visited(N, vector<bool>(M, false));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(graph[i][j] == 1){
                dfs(graph, i, j, visited, res);
            }
        }
    }
    cout << res;
    return 0;
}

102. 沉没孤岛

先将四条边相连的地块都置为2,最后再全部遍历,将为1 为0的都置零,为2的置为1

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void dfs(vector<vector<int>>& graph, int x, int y){
    graph[x][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 >= graph.size() || nexty < 0 || nexty >= graph[0].size()){
            continue;
        }
        if(graph[nextx][nexty] == 1){
            dfs(graph, nextx, nexty);
        }
    }
}
int main(){
    int N, M;
    cin >> N >> M;
    vector<vector<int>> graph(N, vector<int>(M, 0));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            cin >> graph[i][j];
        }
    }
    for(int i = 0; i < N; i++){
        if(graph[i][0] == 1){
            dfs(graph, i, 0);
        }
        if(graph[i][M - 1] == 1){
            dfs(graph, i, M - 1);
        }
    }
    for(int j = 0; j < M; j++){
        if(graph[0][j] == 1){
            dfs(graph, 0, j);
        }
        if(graph[N - 1][j] == 1){
            dfs(graph, N - 1, j);
        }
    }
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M - 1; j++){
            if(graph[i][j] == 1){
                graph[i][j] = 0;
            }
            if(graph[i][j] == 2){
                graph[i][j] = 1;
            }
            cout << graph[i][j] << " ";
        }
        if(graph[i][M - 1] == 2){
            graph[i][M - 1] = 1;
        }
        cout << graph[i][M - 1] << endl;
    }
    return 0;
}

103. 高山流水

可以从边往中间搜,这样只用搜索四条边,不需要全部遍历

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void dfs(vector<vector<int>>& graph, vector<vector<bool>>& Border, int x, int y){
    if(Border[x][y]){
        return;
    }
    Border[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 >= graph.size() || nexty < 0 || nexty >= graph[0].size()){
            continue;
        }
        if(graph[nextx][nexty] >= graph[x][y]){
            dfs(graph, Border, nextx, nexty);
        }
    }
}
int main(){
    int N, M;
    cin >> N >> M;
    vector<vector<int>> graph(N, vector<int>(M, 0));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            cin >> graph[i][j];
        }
    }

    vector<vector<bool>> firstBorder(N, vector<bool>(M, false));
    vector<vector<bool>> secondBorder(N, vector<bool>(M, false));

    for(int i = 0; i < N; i++){
        dfs(graph, firstBorder, i, 0);
        dfs(graph, secondBorder, i, M - 1);
    }
    for(int j = 0; j < M; j++){
        dfs(graph, firstBorder, 0, j);
        dfs(graph, secondBorder, N - 1, j);
    }
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(firstBorder[i][j] && secondBorder[i][j]){
                cout << i  << " " << j << endl;
            }
        }
    }
    return 0;
}

104. 建造最大岛屿

遍历二维网格,通过将一个海洋格子(0)改为陆地(1),找到改造后能形成的最大岛屿面积(岛屿为上下左右相邻的陆地)。

标记岛屿 & 统计面积

遍历网格,对每个未标记的陆地(1),用 DFS 遍历其连通区域,将该区域所有格子标记为唯一岛屿编号(从 2 开始);

记录每个岛屿编号对应的面积,同时保存原始最大岛屿面积(无改造时的最大值)。

计算改造海洋的最大收益

遍历每个海洋格子(0),统计其四个方向相邻的不同岛屿面积之和(用集合去重,避免重复加同一岛屿);

该和 + 1(改造的海洋格子本身)即为改造后岛屿面积,更新全局最大面积。

初始最大面积设为 1(应对全海洋场景:改造 1 个格子成陆地,面积为 1);

遍历海洋时先做边界检查,避免数组越界。

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

int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void dfs(vector<vector<int>>& graph, int x, int y, int &areaSum, int islandId){
    graph[x][y] = islandId;
    areaSum++;
    for(int i = 0; i < 4; i++){
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];

        if(nextx < 0 || nexty < 0 || nextx >= graph.size() || nexty >= graph[0].size()){
            continue;
        }
        if(graph[nextx][nexty] == 1){
            dfs(graph, nextx, nexty, areaSum, islandId);
        }
    }

}

int main(){
    int N, M;
    cin >> N >> M;
    vector<vector<int>> graph(N, vector<int>(M, 0));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            cin >> graph[i][j];
        }
    }
    int islandId = 2;
    int res = 1;
    unordered_map<int, int> mp;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(graph[i][j] == 1){
                int sum = 0;
                dfs(graph, i, j, sum, islandId);
                mp[islandId] = sum;
                islandId++;
                res = max(res, sum);
            }
        }
    }

    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(graph[i][j] == 0){
                int curSum = 1;
                unordered_set<int> st;
                for(int k = 0; k < 4; k++){
                    int nextx = i + dir[k][0];
                    int nexty = j + dir[k][1];
                    if(nextx < 0 || nexty < 0 || nextx >= graph.size() || nexty >= graph[0].size()){
                        continue;
                    }
                    if(graph[nextx][nexty] == 0 || st.count(graph[nextx][nexty]) != 0) {
                        continue;
                    }

                    else {
                        curSum += mp[graph[nextx][nexty]];
                        res = max(res, curSum);
                        st.insert(graph[nextx][nexty]);
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}
相关推荐
起个名字费劲死了18 分钟前
VisionMaster集成深度学习算法(基础狗)
人工智能·深度学习·算法
lengxuenong21 分钟前
枚举例题分析
c++·算法·青少年编程
Navigator_Z39 分钟前
LeetCode //C - 1269. Number of Ways to Stay in the Same Place After Some Steps
c语言·算法·leetcode
2601_9657422242 分钟前
短视频脚本创作方法分享:本地生活类账号的起步思路
大数据·人工智能·算法·ai·新媒体运营·生活
55873生态系统手记1 小时前
读完 55873 资产钱包的技术栈,我重新理解了 "合规钱包" 应该长什么样
算法·架构
旋生万物1 小时前
素数螺旋映射 $z_n=n^{1+i}$ 的角分布统计检验与零模型对比
大数据·前端·人工智能·算法·云原生·螺旋生成论·螺旋相位
HRTOS1 小时前
HRTOS Shell继续完善:优化printf缓冲区与字符串越界保护,国庆后随新版本更新
运维·单片机·嵌入式硬件·算法·51单片机
邵奈一1 小时前
当沉香之乡遇上 Seed-2.1-pro:我用 AI 给村子做了一个数字门面
算法·架构
海天一色y2 小时前
图像分割全解析:从经典算法到深度学习的原理与实战(Python + MATLAB)
python·深度学习·算法
垆边人似月.2 小时前
华为算法题:最长连续递增子序列的变
数据结构·算法·leetcode