(算法)⻜地的数量————<多源BFS>

1. 题⽬链接:1020.⻜地的数量

2. 题⽬描述:

3. 解法:

算法思路:

正难则反:

从边上的1 开始搜索,把与边上1 相连的联通区域全部标记⼀下;然后再遍历⼀遍矩阵,看看哪些位置的1 没有被标记即可 标记的时候,可以⽤「多源bfs 」解决。

C++算法代码: 

class Solution 
{
public:
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int numEnclaves(vector<vector<int>>& grid) 
    {
        int count=0;
        int m=grid.size(),n=grid[0].size();
        vector<vector<int>>answer(m,vector<int>(n,-1));  //答案
        queue<pair<int,int>>q;
        //第一行+最后一行
        for(int i=0;i<n;i++)
        {
            if(answer[0][i]==-1&&grid[0][i]==1)
            {
                answer[0][i]=1;
                q.push({0,i});
            }
            if(answer[m-1][i]==-1&&grid[m-1][i]==1)
            {
                answer[m-1][i]=1;
                q.push({m-1,i});
            }
        }
        //第一列+最后一列
        for(int i=0;i<m;i++)
        {
            if(answer[i][0]==-1&&grid[i][0]==1)
            {
                answer[i][0]=1;
                q.push({i,0});
            }
            if(answer[i][n-1]==-1&&grid[i][n-1]==1)
            {
                answer[i][n-1]=1;
                q.push({i,n-1});
            }
        }
        //多节点同时拓展
        while(q.size())
        {
            int lenth=q.size();
            for(int i=0;i<lenth;i++)
            {
                auto[a,b]=q.front();
                q.pop();
                for(int j=0;j<4;j++)
                {
                    int x=a+dx[j],y=b+dy[j];
                    if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]==1&&answer[x][y]==-1)
                    {
                        answer[x][y]=1;
                        q.push({x,y});
                    }
                }
            }
        }
        //计算剩余陆地个数
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(answer[i][j]==-1&&grid[i][j]==1)
                {
                    count++;
                }
            }
        }
        return count;
    }
};

Java算法代码:

class Solution
{
	int[] dx = { 0, 0, 1, -1 };
	int[] dy = { 1, -1, 0, 0 };
	1
		2
		3
		4
		5 public int numEnclaves(int[][] grid)
	{
		int m = grid.length, n = grid[0].length;
		boolean[][] vis = new boolean[m][n];
		Queue<int[]> q = new LinkedList<>();
		// 1. 把边上的 1 全部加⼊到队列中 
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
				if (i == 0 || i == m - 1 || j == 0 || j == n - 1)
				{
					if (grid[i][j] == 1)
					{
						q.add(new int[] {i, j});
						vis[i][j] = true;
					}
				}
		// 2. 多源 bfs 
		while (!q.isEmpty())
		{
			int[] t = q.poll();
			int a = t[0], b = t[1];
			for (int i = 0; i < 4; i++)
			{
				int x = a + dx[i], y = b + dy[i];
				if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 &&
					!vis[x][y])
				{
					q.add(new int[] {x, y});
					vis[x][y] = true;
				}
			}
		}
		// 3. 提取结果 
		int ret = 0;
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
				if (grid[i][j] == 1 && !vis[i][j])
					ret++;
		return ret;
	}
}
在图论中,给定一个无向图,寻找最少颜色着色的问题属于经典的图染色问题,特别是对于最小颜色问题(也称为独立集或顶点着色),目标是最小化使用的颜色数,使得每个顶点都被恰好一个颜色覆盖,且没有相邻的顶点颜色相同。在这种情况下,我们想要找到一种策略,使得每个连通分量最多使用不同颜色的数量。 这个问题可以通过经典算法如贪心策略、递归回溯(如分支限界法)或者更复杂的方法如Kosaraju's Algorithm或Vizing's Theorem来解决。然而,由于这需要编写代码并实现具体的算法,这里我将提供一个简单的思路和基本的C++框架,但不包括完整的程序。 首先,我们可以使用邻接矩阵来存储地图。邻接矩阵是一个二维数组,其中行代表起点,列表代表终点,值为1表示有边连接。 ```cpp #include <vector> #include <algorithm> // 邻接矩阵表示 std::vector<std::vector<int>> adjacencyMatrix = { {0, 1, 1, 1, 1, 1, 0, 0, 0}, // 1 到 ... {1, 0, 1, 0, 0, 0, 1, 0, 0}, // 2 到 ... // ... // 以此类推,直到最后一个顶点 }; // 假设函数dfs的颜色数组,用于记录每个顶点的颜色 std::vector<int> colors; // 基本的深度优先搜索(DFS)或广度优先搜索(BFS)辅助函数 void dfs(int vertex, int color) { colors[vertex] = color; for (int neighbor : adjacencyMatrix[vertex]) { if (colors[neighbor] == 0) { // 如果邻居还没被染色 dfs(neighbor, color + 1); // 从当前颜色+1开始尝试 } else if (colors[neighbor] == color) { // 如果相邻节点颜色相同,无法染色,退出 return; } } } // 主函数:最小颜色染色 int minColoring() { int minColors = 0; // 初始化为0,最坏情况下需要染色 colors.resize(verticesCount, 0); for (int i = 0; i < verticesCount; ++i) { if (colors[i] == 0) { bool success = true; // 是否找到可行方案 for (int color = 1; success && color <= minColors + 1; ++color) { dfs(i, color); if (colors == color) { // 如果找到了一个颜色组合 minColors = color; // 更新最少颜色 success = false; // 已经找到最优解,停止尝试 } } } } return minColors; } int main() { int verticesCount = adjacencyMatrix.size(); // 获取顶点数 int minColoredVertices = minColoring(); std::cout << "使用最少的颜色是: " << minColoredVertices << std::endl; return 0; } ``` 这个例子只是一个基础框架,实际的最小颜色染色可能需要更复杂的搜索算法,或者使用启发式方法(如贪心算法或局部搜索)。请注意,由于实际地图的具体信息未给出,这个示例是基于假设的邻接矩阵结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值