【C++算法】BFS解決多源最短路問題相關經典算法題

1.01矩陣

既然本章是BFS解決多源最短路問題,也就是說有若干個起點,那我們就可以暴力一點,直接把多源最短路徑問題轉化成若干個單源最短路徑問題,然后將每次的步數比較一下,取到最短的就是最短路徑的結果,這個想法好寫,但是在本章都會超時,所以我們換一個思路:把所有的源點當成一個超級源點(包含所有的源點),那么問題就變成了單一的單源最短路徑問題,此時我們使用一次bfs就可以解決問題。但是如何將這個源點當作一個超級源點呢?在解決單源最短路問題,我們的做法是把起點加入到隊列,然后一層一層的往外擴展,所以我們只需要一開始將所有的起點都加入到隊列,然后一層一層往外擴展即可,我們直接看第一個思路:

代碼我已經替大家試過了,會超時,所以我們來看第二種思路:

直接上代碼:

class Solution {int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};
public:vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {int m = mat.size();int n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));// dist[i][j] == -1,表示:沒有被搜索過// dist[i][j] != -1,表示:最短距離// 利用dist來直接標記該位置是否已經被使用queue<pair<int,int>> q;// 把所有為0的源點加入隊列中for(int i = 0; i < m; i++)  for(int j = 0; j < n; j++)if(mat[i][j] == 0){q.push({i, j});dist[i][j] = 0;}while(q.size()){// 此時我們不需要同時向外擴展// 因此不需要使用szauto [a, b] = q.front();q.pop();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 && dist[x][y] == -1){// 此時說明已經找到,直接修改dist的值即可dist[x][y] = dist[a][b] + 1;q.push({x, y});}}}return dist;}
};

2.飛地的數量

這道題目如果我們按照每次遍歷數組每次遇到1就去bfs,肯定是會超時的,但是根據這個寫法也有不超時的做法,我們遍歷的時候,遇到1就去bfs,并將途中遇到1的位置標記一下,下一輪遇到1的時候,先dfs一下,如果這次dfs寬搜的時候遇到1,發現這個位置已經標記過,此時就不要bfs了,直接就是上次的結果,但是這樣寫需要兩次dfs,并且dsf的代碼還不一樣,也比較麻煩,那我們來一個新思路:正難則反,我們可以從邊上的 1 開始搜索,把與邊上 1 相連的聯通區域全部標記?下; 然后再遍歷?遍矩陣,看看哪些位置的 1 沒有被標記即可標記的時候,可以用「多源 bfs 」解決,bfs的邏輯和上一個題目基本差不多,直接上代碼。

class Solution {int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};bool vis[501][501] = {false};
public:int numEnclaves(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();// 1. 把邊上的 1 加?到隊列中queue<pair<int,int>> q;// 遍歷行for(int i = 0; i < n; i++){if(grid[0][i] == 1)q.push({0, i});if(grid[m - 1][i] == 1)q.push({m - 1, i});}// 遍歷列for(int j = 0; j < m; j++){if(grid[j][0] == 1)q.push({j, 0});if(grid[j][n - 1] == 1)q.push({j, n - 1});}// 2. 多源bfswhile(q.size()){auto [a, b] = q.front();q.pop();vis[a][b] = true;for(int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y]){q.push({x, y});vis[x][y] = true;}}}// 統計結果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;       }
};

3.地圖中的最高點

注意本題給的是結果矩陣,我們可以先來看看原始矩陣的樣子

此時就一目了然了,我們直接創建一個height數組,將isWater中的水域依次向外擴展,直接轉化成多源bfs的問題,并且我們發現它就是01矩陣的變型題,直接上代碼了:

class Solution {int dx[4] = { 0, 0, 1, -1 };int dy[4] = { 1, -1, 0, 0 };
public:vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {int m = isWater.size();int n = isWater[0].size();// 數組不能初始化為0,因為數組中存在0 - 代表水域vector<vector<int>> height(m, vector<int>(n, -1));queue<pair<int, int>> q;// 把所有的源點加入到隊列里面for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (isWater[i][j] == 1){height[i][j] = 0;q.push({ i,j });}// 多源bfswhile (q.size()){auto [a, b] = q.front();q.pop();for (int i = 0; i < 4; i++){int x = a + dx[i];int y = b + dy[i];// 該值沒有被搜索過if (x >= 0 && x < m && y >= 0 && y < n && height[x][y] == -1){height[x][y] = height[a][b] + 1;q.push({ x, y });}}}return height;}
};

4.地圖分析

我們這個題目要求解海洋到陸地的最大距離,也可以求,但是海洋數量多蠻煩,正難則反,我們可以求陸地到海洋,將陸地作為超級源點依次向外擴展,隨后創建一個dist數組,記錄每次bfs的值保存在ist數組中即可解決,代碼和上面的題目都相似,直接上代碼:

class Solution
{int dx[4] = { 0, 0, 1, -1 };int dy[4] = { 1, -1, 0, 0 };
public:int maxDistance(vector<vector<int>>& grid){int m = grid.size(), n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> q;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (grid[i][j] == 1){dist[i][j] = 0;q.push({ i, j });}int ret = -1;while (q.size()){auto [a, b] = q.front(); q.pop();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 && dist[x][y] == -1){dist[x][y] = dist[a][b] + 1;q.push({ x, y });ret = max(ret, dist[x][y]);}}}return ret;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/14831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14831.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/14831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

arcgis 10.6 工具欄操作error 001143 后臺服務器拋出異常

arcgis 10.6 工具欄操作error 001143 后臺服務器拋出異常 環境 win10arcgis 10.6 問題 執行定義投影要素轉線出現 Error: 001143:后臺服務器拋出異常&#xff08;差點重裝10.6&#xff09; 如下圖所示&#xff1a; 解決方法 通過在菜單工具條上單擊地理處理 > 地理處…

設計模式使用(成本扣除)

前言 名詞解釋 基礎名詞 訂單金額&#xff1a;用戶下單時支付的金額&#xff0c;這個最好理解 產品分成&#xff1a;也就是跟其他人合做以后我方能分到的金額&#xff0c;舉個例子&#xff0c;比如用戶訂單金額是 100 塊&#xff0c;我方的分成是 80%&#xff0c;那么也就是…

OceanMind海睿思通過上海數交所數商認證,提供高質量數據治理和數據咨詢服務

近日&#xff0c;中新賽克海睿思成功通過上海數據交易所的數商認證&#xff0c;獲得上海數據交易所頒發的“數據產品開發服務商”、“數據治理服務商”和“數據咨詢服務商”三大證書。 作為由深圳市創新投資集團有限公司投資控股的高新技術企業&#xff0c;國家級專精特新“小巨…

如何通過OpenHarmony的音頻模塊實現錄音變速功能?

簡介 OpenAtom OpenHarmony&#xff08;以下簡稱“OpenHarmony”&#xff09;是由開放原子開源基金會孵化及運營的開源項目&#xff0c;是面向全場景、全連接、全智能時代的智能物聯網操作系統。 多媒體子系統是OpenHarmony系統中的核心子系統&#xff0c;為系統提供了相機、…

2024-05-24 問AI: 在深度學習中,什么是L1 正則化和L2 正則化?

文心一言 在深度學習和機器學習中&#xff0c;正則化是一種用于防止模型過擬合的技術。它通過向損失函數添加一個懲罰項來實現&#xff0c;這個懲罰項與模型的復雜度有關。正則化項可以看作是對模型參數的約束&#xff0c;使得模型在訓練時不僅關注于最小化訓練誤差&#xff0…

Java入門基礎學習筆記43——包

什么是包&#xff1f; 包是用來分門別類的管理各種不同程序的&#xff0c;類似文件夾&#xff0c;建包有利于程序的管理和維護。 建包的語法規則&#xff1a; package cn.ensource.javabean;public class Car() {} 在自己的程序中調用其他包下的程序的注意事項&#xff1a; 1…

動手學深度學習——層和塊

1. 層 層是一個將輸入數據轉換為輸出數據的神經網絡組件。每個層都會對輸入數據進行一定的操作&#xff0c;例如線性變換、非線性激活函數等&#xff0c;以產生輸出數據。 torch.nn模塊提供了各種預定義的層&#xff0c;如線性層、卷積層、池化層等&#xff0c; nn.Linear&a…

BLE學習筆記(0.0) —— 基礎概念(0)

前言 &#xff08;1&#xff09;本章節主要是對BLE技術進行簡單的介紹&#xff0c;熟悉藍牙技術的發展過程&#xff0c;了解相關術語方便后續的學習。 &#xff08;2&#xff09;為了防止單篇博客太長以至于看不下去&#xff0c;因此我基礎概念章節分為兩篇來寫。 &#xff08;…

直播回放| 機器人任務挑戰賽線上培訓資料合集

大賽培訓回顧 5月22日&#xff0c;卓翼飛思實驗室為全國各賽區精心組織的機器人任務挑戰賽&#xff08;無人協同系統&#xff09;線上培訓第三期順利落下帷幕&#xff0c;吸引300余人參與。本次培訓主要針對仿真平臺的基本使用&#xff0c;從仿真平臺獲取激光雷達/視覺數據&am…

Mysql教程(0):學習框架

1、Mysql簡介 MySQL 是一個開放源代碼的、免費的關系型數據庫管理系統。在 Web 開發領域&#xff0c;MySQL 是最流行、使用最廣泛的關系數據庫。MySql 分為社區版和商業版&#xff0c;社區版完全免費&#xff0c;并且幾乎能滿足全部的使用場景。由于 MySQL 是開源的&#xff0…

選擇排序,改進冒泡排序,快速排序的查找和計數排序

簡單選擇排序 數據結構:單鏈表 實現方法:n為鏈表長度, 第1趟先選出1到n-1個元素中的最小值和0號元素交換, 第2趟從2到n-1號元素選出最小值和1號元素交換, … 第n-2趟從n-2到n-1號元素中選出最小值和n-2號元素交換. 第n-1趟n-1號元素即為最小值。比較結束。 代碼:…

1075: 求最小生成樹(Prim算法)

解法&#xff1a; 總結起來&#xff0c;Prim算法的核心思想是從一個頂點開始&#xff0c;一步一步地選擇與當前最小生成樹相鄰的且權值最小的邊&#xff0c;直到覆蓋所有的頂點&#xff0c;形成一個最小生成樹。 #include<iostream> #include<vector> using names…

算法-跳馬

bfs類的應用題。 解法&#xff1a; 每一個點都可能作為匯集的那個點&#xff0c;因此采用遍歷的方式&#xff0c;對每個點進行處理&#xff0c;得出每個點的“所有馬跳到本點的最小步數和“&#xff0c;取最小值即可。 邏輯1&#xff1a;以該點作為源點出發&#xff0c;求處…

springboot基于Web前端技術的java養老院管理系統_utbl7

3.普通用戶模塊包括&#xff1a;普通會員的注冊、養老院客房查詢、養老院留言查詢、預約老人基本信息登記、選擇房間、用戶繳費的功能。 4.數據信息能夠及時進行動態更新&#xff0c;增刪&#xff0c;用戶搜素方便&#xff0c;使用戶可以直接瀏覽相關信息&#xff0c;要考慮便于…

Vue3實戰筆記(35)—集成炫酷的粒子特效

文章目錄 前言一、vue3使用tsparticles二、使用步驟總結 前言 學習一個有趣炫酷的玩意開心一下。 tsparticles&#xff0c;可以方便的實現各種粒子特效。支持的語言框架也是相當的豐富. 官網&#xff1a;https://particles.js.org/ 一、vue3使用tsparticles 先來個vue3使用…

Go 語言逃逸分析:內存管理的關鍵

文章目錄 前言1 逃逸分析是什么&#xff1f;2 逃逸分析的基本思想是什么&#xff1f;3 逃逸分析的分配原則是什么&#xff1f;4 如何進行逃逸分析&#xff1f;5 逃逸分析案例5.1 變量在函數外存在引用5.2 引用類型的逃逸5.3 閉包捕獲變量5.4 變量占用內存較大 6 變量會逃逸到堆…

代碼隨想錄訓練營打卡第36天:動態規劃解決子序列問題

1.300最長遞增子序列 1.問題描述 找到其中最長嚴格遞增子序列的長度。 子序列 是由數組派生而來的序列&#xff0c;刪除&#xff08;或不刪除&#xff09;數組中的元素而不改變其余元素的順序。 2.問題轉換 從nums[0...i]的最長的遞增的子序列 3.解題思路 每一個位置的n…

經濟學問題

問題1 1916年&#xff0c;福特汽車公司以440美元的價格生產了50萬輛T型福特汽車。該公司當年盈利6000萬美元。亨利福特告訴一位報紙記者&#xff0c;他打算把T型車的價格降至360美元&#xff0c;他希望在這個價格上能賣出80萬輛汽車。福特說&#xff1a;“每輛車的利潤減少&am…

Flutter 中的 CupertinoPicker 小部件:全面指南

Flutter 中的 CupertinoPicker 小部件&#xff1a;全面指南 在Flutter中&#xff0c;CupertinoPicker是一個用于創建iOS風格的選擇器的組件&#xff0c;它允許用戶通過滾動來選擇一個值。CupertinoPicker可以用于選擇日期、時間或者任何可枚舉的值。本文將詳細介紹CupertinoPi…

C++多態詳解

目錄 一、多態的概念 二、多態的定義及實現 1.多態的構成條件 2.虛函數 3.虛函數的重寫 4.例題理解&#xff08;超級重要&#xff0c;強烈建議做一下&#xff09; 5.C11 override和 final 6.重載、覆蓋&#xff08;重寫&#xff09;、隱藏&#xff08;重定義&#xff0…