代碼隨想錄算法訓練營四十三天|圖論part01

深度優先搜索(dfs)理論基礎

dfs就是可一個方向去搜直到盡頭再換方向,換方向的過程就涉及到了回溯。

代碼框架

因為dfs搜索可一個方向,并需要回溯,所以用遞歸的方式來實現是最方便的。

先來回顧一下回溯法的代碼框架:

void backtracking(參數) {if (終止條件) {存放結果;return;}for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小)) {處理節點;backtracking(路徑,選擇列表); // 遞歸回溯,撤銷處理結果}
}

據此給出dfs的代碼框架:

void dfs(參數) {if (終止條件) {存放結果;return;}for (選擇:本節點所連接的其他節點) {處理節點;dfs(圖,選擇的節點); // 遞歸回溯,撤銷處理結果}
}

所有可達路徑

題目鏈接:98. 所有可達路徑 (kamacoder.com)

【題目描述】

給定一個有 n 個節點的有向無環圖,節點編號從 1 到 n。請編寫一個程序,找出并返回所有從節點 1 到節點 n 的路徑。每條路徑應以節點編號的列表形式表示。

【輸入描述】

第一行包含兩個整數 N,M,表示圖中擁有 N 個節點,M 條邊

后續 M 行,每行包含兩個整數 s 和 t,表示圖中的 s 節點與 t 節點中有一條路徑

【輸出描述】

輸出所有的可達路徑,路徑中所有節點的后面跟一個空格,每條路徑獨占一行,存在多條路徑,路徑輸出的順序可任意。

如果不存在任何一條路徑,則輸出 -1。

注意輸出的序列中,最后一個節點后面沒有空格! 例如正確的答案是?1 3 5,而不是?1 3 5, 5后面沒有空格!

輸入示例

5 5
1 3
3 5
1 2
2 4
4 5

輸出示例

1 3 5
1 2 4 5

提示信息

用例解釋:

有五個節點,其中的從 1 到達 5 的路徑有兩個,分別是 1 -> 3 -> 5 和 1 -> 2 -> 4 -> 5。

因為擁有多條路徑,所以輸出結果為:

1 3 5
1 2 4 5

1 2 4 5
1 3 5
都算正確。

數據范圍:

圖中不存在自環
圖中不存在平行邊
1 <= N <= 100
1 <= M <= 500

使用鄰接矩陣存儲

使用二維數組來表示圖,因為有n個節點,節點編號從1開始,所以我們申請(n+1)*(n+1)大的二維數組;然后構造m個邊:

int[][] graph=new int[n+1][n+1];
for(int i=0;i<m;i++){int a=in.nextInt();int b=in.nextInt();graph[a][b]=1;
}

使用鄰接矩陣存儲dfs的代碼:

public static void dfs(List<List<Integer>> graph, int x, int n) { //x表示當前遍歷到的節點if (x == n) {res.add(new ArrayList<>(list));return;}for(int i=1;i<=n;i++){if(graph[x][i]==1){list.add(i);dfs(graph,i,n);list.remove(list.size()-1);}}}

打印結果:

for(List<Integer> tmp:res){for(int i=0;i<tmp.size()-1;i++){System.out.print(tmp.get(i)+" ");}System.out.println(tmp.get(tmp.size()-1));
}

整體代碼如下:

import java.util.*;public class Main{static List<List<Integer>> res=new ArrayList<List<Integer>>();static List<Integer> list=new ArrayList<>();public static void main(String[] args){Scanner in=new Scanner(System.in);int n=in.nextInt();int m=in.nextInt();int[][] graph=new int[n+1][n+1];for(int i=0;i<m;i++){int a=in.nextInt();int b=in.nextInt();graph[a][b]=1;}list.add(1);dfs(graph,1,n);if(res.isEmpty())System.out.println(-1);for(List<Integer> tmp:res){for(int i=0;i<tmp.size()-1;i++){System.out.print(tmp.get(i)+" ");}System.out.println(tmp.get(tmp.size()-1));}}public static void dfs(int[][] graph,int x,int n){//x表示當前遍歷到的節點if(x==n){res.add(new ArrayList<>(list));return;}for(int i=1;i<=n;i++){if(graph[x][i]==1){list.add(i);dfs(graph,i,n);list.remove(list.size()-1);}}}
}

使用鄰接表存儲

List<List<Integer>> graph = new ArrayList<List<Integer>>(n + 1);for(int i=0;i<=n;i++){graph.add(new ArrayList<>());}for (int i = 0; i < m; i++) {int a = in.nextInt();int b = in.nextInt();graph.get(a).add(b);}

使用領接表存儲的dfs的寫法:

public static void dfs(List<List<Integer>> graph, int x, int n) { //x表示當前遍歷到的節點if (x == n) {res.add(new ArrayList<>(list));return;}for (int i : graph.get(x)) {list.add(i);dfs(graph, i, n);list.remove(list.size() - 1);}}

打印結果:

if (res.isEmpty()) System.out.println(-1);for (List<Integer> tmp : res) {for (int i = 0; i < tmp.size() - 1; i++) {System.out.print(tmp.get(i) + " ");}System.out.println(tmp.get(tmp.size() - 1));}

整體代碼如下:

import java.util.*;public class Main {static List<List<Integer>> res = new ArrayList<List<Integer>>();static List<Integer> list = new ArrayList<>();public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();int m = in.nextInt();//鄰接表寫法List<List<Integer>> graph = new ArrayList<List<Integer>>(n + 1);for(int i=0;i<=n;i++){graph.add(new ArrayList<>());}for (int i = 0; i < m; i++) {int a = in.nextInt();int b = in.nextInt();graph.get(a).add(b);}list.add(1);dfs(graph, 1, n);if (res.isEmpty()) System.out.println(-1);for (List<Integer> tmp : res) {for (int i = 0; i < tmp.size() - 1; i++) {System.out.print(tmp.get(i) + " ");}System.out.println(tmp.get(tmp.size() - 1));}}public static void dfs(List<List<Integer>> graph, int x, int n) { //x表示當前遍歷到的節點if (x == n) {res.add(new ArrayList<>(list));return;}for (int i : graph.get(x)) {list.add(i);dfs(graph, i, n);list.remove(list.size() - 1);}}
}

廣度優先搜索(bfs)理論基礎

bfs就是先把本節點所連接的所有節點遍歷一遍,走到下一個節點的時候,再把連接該節點的所有節點遍歷一遍,四面八方的搜索過程。

代碼模板

private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};//表示四個方向
// grid 是地圖,也就是一個二維數組
// visited標記訪問過的節點,不要重復訪問
// x,y 表示開始搜索節點的下標public static void bfs(char[][] grid, boolean[][] visited, int x, int y) {// 定義隊列,存儲坐標對Queue<int[]> queue = new LinkedList<>();// 起始節點加入隊列queue.offer(new int[]{x, y});// 只要加入隊列,立刻標記為訪問過的節點visited[x][y] = true;// 開始遍歷隊列里的元素while (!queue.isEmpty()) {// 從隊列取出元素int[] current = queue.poll();int curx = current[0];int cury = current[1];// 向當前節點的四個方向(上下左右)遍歷for (int i = 0; i < 4; i++) {// 獲取周邊四個方向的坐標int nextx = curx + dir[i][0];int nexty = cury + dir[i][1];// 檢查坐標是否越界,如果越界直接跳過if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) {continue;}// 如果節點沒被訪問過if (!visited[nextx][nexty]) {// 將該節點加入隊列,作為下一輪要遍歷的節點queue.offer(new int[]{nextx, nexty});// 只要加入隊列立刻標記,避免重復訪問visited[nextx][nexty] = true;}}}}

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

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

相關文章

飛算JavaAI金融風控場景實踐:從實時監測到智能決策的全鏈路安全防護

目錄一、金融風控核心場景的技術突破1.1 實時交易風險監測系統1.1.1 高并發交易數據處理1.2 智能反欺詐系統架構1.2.1 多維度欺詐風險識別1.3 動態風控規則引擎1.3.1 風控規則動態管理二、金融風控系統效能升級實踐2.1 風控模型迭代加速機制2.1.1 自動化特征工程結語&#xff1…

Vue 組件二次封裝透傳slots、refs、attrs、listeners

最近寫了一個開源項目&#xff0c;有些地方需要二次封裝&#xff0c;需要透傳一些數據&#xff0c;需要注意的是ref&#xff0c;我這里使用倆種方式間接傳遞ref&#xff0c;具體如下&#xff1a; 使用&#xff1a; import VideoPlayer from ./index.jsVue.use(VideoPlayer)inde…

介紹大根堆小根堆

文章目錄一、核心定義與結構特性示例&#xff08;以“數組存儲堆”為例&#xff09;二、堆的兩個核心操作1. 插入操作&#xff08;以小根堆為例&#xff09;2. 刪除極值操作&#xff08;以小根堆為例&#xff0c;刪除根節點的最小值&#xff09;三、小根堆 vs 大根堆&#xff1…

【Html網頁模板】賽博朋克數據分析大屏網頁

目錄專欄導讀? 項目概述&#x1f3a8; 設計理念&#x1f6e0;? 技術架構核心技術棧設計模式&#x1f3af; 核心功能1. 視覺效果系統&#x1f308; 色彩體系2. 數據可視化模塊&#x1f4ca; 主圖表系統&#x1f4c8; 性能監控面板3. 實時數據流系統? 數據流動畫&#x1f4ca;…

【經典上穿突破】副圖/選股指標,雙均線交叉原理,對價格波動反應靈敏,適合捕捉短期啟動點

【經典上穿突破】副圖/選股指標&#xff0c;雙均線交叉原理&#xff0c;對價格波動反應靈敏&#xff0c;適合捕捉短期啟動點 這是一款結合短線與中線信號的趨勢跟蹤指標&#xff0c;通過雙均線交叉原理捕捉股價突破時機&#xff0c;適用于個股分析和盤中選股。 核心功能模塊&…

RK3568 NPU RKNN(四):RKNN-ToolKit2性能和內存評估

文章目錄1、前言2、目標3、完整的測試程序4、運行測試程序5、程序拆解6、總結1、前言 本文僅記錄本人學習過程&#xff0c;不具備教學指導意義。 2、目標 使用野火提供的示例程序&#xff0c;體驗 RKNN-ToolKit2 在PC端使用連板推理&#xff0c;進行性能和內存評估。 3、完…

ASP.NET 上傳文件安全檢測方案

一、前端初步過濾&#xff08;防誤操作&#xff09;<!-- HTML部分 --><input type"file" id"fileUpload" accept".jpg,.png,.pdf,.docx" /><button onclick"validateFile()">上傳</button><script>func…

Nacos Server 3.0.x安裝教程

前言 注&#xff1a; 1.Nacos Server 3.0.x 要求 JDK版本不低于17。 2.Nacos 2.2.0 及以上版本需要 Java 11 或更高版本。 3.Java 8&#xff0c;需要下載 Nacos 2.1.x 及以下版本 JDK17安裝 JDK官方下載地址&#xff1a;Oracle官網JDK下載地址 JDK17&#xff1a;JDK17下載地…

【數據庫干貨】六大范式速記

1NF、2NF、3NF、BCNF、4NF、5NF都是數據庫設計中的范式&#xff08;Normalization&#xff09;&#xff0c;用于確保數據庫中的數據結構盡可能地減少冗余&#xff0c;避免更新異常、插入異常、刪除異常等問題&#xff0c;從而提高數據的存儲效率和一致性。 本篇文章簡單講解下各…

Java開發主流框架搭配詳解及學習路線指南

文章目錄一、前言&#x1f517;二、主流Java框架搭配2.1 Spring Boot MyBatis-Plus Spring Cloud2.2 Spring Boot Spring Data JPA Spring Cloud2.3 Quarkus/Vert.x (響應式編程棧)三、技術選型建議四、Java學習路線指南階段1&#xff1a;Java基礎 (4-6周)階段2&#xff1a…

flutter-使用device_info_plus獲取手機設備信息完整指南

文章目錄1. 概述2. 安裝與配置3. 基本使用方法3.1. 創建實例3.2. 區分平臺獲取信息4. 詳細信息獲取4.1. Android 設備信息4.2. iOS 設備信息4.3. Web 瀏覽器信息4.4. Windows 設備信息5. 實戰示例6. 注意事項6.1. 權限問題6.2. 隱私保護6.3. 平臺差異處理6.4. 性能考慮7. 常見問…

Java 時間處理 API 全解析:從 JDK7 到 JDK8 的演進

個人主頁-愛因斯晨 友友們&#xff0c;互三咯~ 目錄 個人主頁-愛因斯晨 ?編輯 前言 一、JDK7 時間處理基石 ——Date 類 &#xff08;一&#xff09;Date 類基本功能 &#xff08;二&#xff09;Date 類的局限性 二、格式化時間好幫手 ——SimpleDateFormat 類 &#…

duiLib 實現鼠標拖動標題欄時,窗口跟著拖動

1、布局文件&#xff0c;窗口需設置可拖動的標題欄區域&#xff1a;2、HandleMessage函數中&#xff0c;處理WM_LBUTTONDOWN消息&#xff0c;判斷鼠標在標題欄&#xff0c;讓系統處理窗口移動。代碼片段如下&#xff1a;else if (uMsg WM_LBUTTONDOWN) {// 獲取鼠標點擊坐標PO…

圖解嵌入式硬件知識庫體系

構建一個嵌入式硬件知識庫體系需要涵蓋嵌入式系統設計、開發和應用的各個方面,內容全面且系統化,適合不同層次的用戶。本文是一個結構化的嵌入式硬件知識庫體系,包含主要內容模塊及其詳細說明。 @startmindmap * 嵌入式硬件知識庫體系 ** 1. 嵌入式系統基礎 *** 概述與定義 …

機器學習的特征工程(特征構造、特征選擇、特征轉換和特征提取)詳解

特征工程是機器學習中至關重要的一步&#xff0c;它直接影響模型的性能和泛化能力。特征構造、特征選擇、特征轉換和特征提取——構成了特征工程的核心流程。下面我來系統地梳理一下它們的定義、方法和應用場景&#xff1a; 整理 by Moshow鄭鍇https://zhengkai.blog.csdn.net/…

Force Dimension觸覺力反饋設備在外科手術機器人遙操作和訓練中的應用

觸覺力反饋設備通過傳感器-執行器-信號處理閉環系統&#xff0c;在外科手術機器人領域實現了從遠程手術操作到虛擬訓練的全流程革新。外科手術機器人外科醫生廣博的專業知識往往受限于他們的主要工具——手。機器人的精確度和靈活性遠遠超過人手。然而&#xff0c;目前機器人還…

【網絡與爬蟲 00】試讀

網絡爬蟲技術全棧指南&#xff1a;從入門到AI時代的數據采集革命 關鍵詞&#xff1a;網絡爬蟲、Python爬蟲、數據采集、反爬技術、分布式爬蟲、AI爬蟲、Scrapy框架、自動化數據提取、爬蟲架構設計 摘要&#xff1a;本專欄是最全面的網絡爬蟲技術指南&#xff0c;涵蓋從基礎框架…

[Chat-LangChain] 前端用戶界面 | 核心交互組件 | 會話流管理

鏈接&#xff1a;https://python.langchain.com/docs/tutorials/qa_chat_history/ Chat-LangChain技術棧 : LangChainLangGraphNext.jsWeaviate (向量存儲)OpenAI (嵌入模型) docs&#xff1a;chat-langchain Chat LangChain 是一個智能聊天機器人&#xff0c;專為解答Lang…

編寫和運行 Playbook

編寫和運行 Playbook Playbook 介紹 adhoc 命令可以作為一次性命令對一組主機運行一項簡單的任務。不過&#xff0c;若要真正發揮Ansible的能力&#xff0c;需要使用功能 playbook。 playbook 是一個文本文件&#xff0c;其中包含由一個或多個按特定順序運行的play組成的列表。…

uniapp手機端video標簽層級過高問題

當我們想以視頻作為背景時&#xff0c;其他dom通過定位顯示在視頻上方&#xff0c;h5頁面上調試發現可以正常使用&#xff0c;效果如下&#xff1a; 當放在手機上看&#xff0c;會發現&#xff0c;僅僅剩一個視頻&#xff0c;本應在視頻上層的元素不見了。 經過一番排查&#x…