【圖論】判斷圖中有環的兩種方法及實現

判斷圖中有環的兩種方法及實現

在圖論中,檢測有向圖是否存在環是常見問題。本文將介紹兩種主流方法:DFS三色標記法拓撲排序(Kahn算法),并提供對應的C++代碼實現。


方法一:DFS三色標記法

核心思想

通過深度優先搜索(DFS)遍歷圖,使用三種顏色標記節點狀態:

  • 0(未訪問):節點尚未被訪問。
  • 1(訪問中):節點正在被訪問,其后續節點仍在遞歸中。
  • 2(已訪問):節點及其所有后代均已處理完畢。

如果在遍歷過程中遇到狀態為1的節點,說明存在環

時間復雜度

  • O(V + E),其中V為節點數,E為邊數。

C++代碼實現

#include <vector>
using namespace std;bool hasCycleDFS(vector<vector<int>>& graph, int node, vector<int>& color) {color[node] = 1; // 標記為“訪問中”for (int neighbor : graph[node]) {if (color[neighbor] == 0) { // 未訪問的節點if (hasCycleDFS(graph, neighbor, color)) return true;} else if (color[neighbor] == 1) { // 遇到訪問中的節點,存在環return true;}}color[node] = 2; // 標記為“已訪問”return false;
}bool hasCycle(vector<vector<int>>& graph) {int n = graph.size();vector<int> color(n, 0); // 初始化所有節點為未訪問for (int i = 0; i < n; ++i) {if (color[i] == 0 && hasCycleDFS(graph, i, color)) {return true;}}return false;
}

方法二:拓撲排序(Kahn算法)

核心思想

  1. 統計每個節點的入度(指向該節點的邊數)。
  2. 將所有入度為0的節點加入隊列。
  3. 依次處理隊列中的節點,減少其鄰居的入度。若鄰居入度變為0,則加入隊列。
  4. 若最終處理的節點數不等于總節點數,則存在環。

時間復雜度

  • O(V + E),其中V為節點數,E為邊數。

C++代碼實現

#include <vector>
#include <queue>
using namespace std;bool hasCycleTopo(vector<vector<int>>& graph) {int n = graph.size();vector<int> indegree(n, 0);queue<int> q;// 計算初始入度for (int u = 0; u < n; ++u) {for (int v : graph[u]) {indegree[v]++;}}// 入度為0的節點入隊for (int i = 0; i < n; ++i) {if (indegree[i] == 0) q.push(i);}int cnt = 0; // 記錄處理的節點數while (!q.empty()) {int u = q.front();q.pop();cnt++;for (int v : graph[u]) {if (--indegree[v] == 0) {q.push(v);}}}return cnt != n; // 存在環時cnt < n
}

方法對比與適用場景

方法優勢劣勢適用場景
DFS三色標記法可同時處理其他任務(如路徑記錄)遞歸深度可能較大需要深度遍歷信息的場景
拓撲排序無需遞歸,適合大規模圖僅提供是否存在環的結果只需判斷環或需要拓撲序列的場景

完整測試代碼

#include <iostream>
#include <vector>
#include <queue>
using namespace std;// DFS三色標記法
bool hasCycleDFS(vector<vector<int>>& graph, int node, vector<int>& color) {color[node] = 1;for (int v : graph[node]) {if (color[v] == 0) {if (hasCycleDFS(graph, v, color)) return true;} else if (color[v] == 1) {return true;}}color[node] = 2;return false;
}bool hasCycleDFS(vector<vector<int>>& graph) {int n = graph.size();vector<int> color(n, 0);for (int i = 0; i < n; ++i) {if (color[i] == 0 && hasCycleDFS(graph, i, color)) {return true;}}return false;
}// 拓撲排序
bool hasCycleTopo(vector<vector<int>>& graph) {int n = graph.size();vector<int> indegree(n, 0);queue<int> q;for (auto& edges : graph) {for (int v : edges) indegree[v]++;}for (int i = 0; i < n; ++i) {if (indegree[i] == 0) q.push(i);}int cnt = 0;while (!q.empty()) {int u = q.front();q.pop();cnt++;for (int v : graph[u]) {if (--indegree[v] == 0) q.push(v);}}return cnt != n;
}int main() {// 示例:有環圖 0->1->2->0vector<vector<int>> graph = {{1}, {2}, {0}};cout << "DFS三色標記法結果: " << (hasCycleDFS(graph) ? "有環" : "無環") << endl;cout << "拓撲排序結果: " << (hasCycleTopo(graph) ? "有環" : "無環") << endl;return 0;
}

通過這兩種方法,可以高效判斷有向圖中是否存在環。實際應用中,若需要拓撲序列則優先選擇Kahn算法,若需深度遍歷信息則選擇DFS三色標記法。

(本文由deepseek總結生成)

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

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

相關文章

11.【線性代數】——矩陣空間,秩1矩陣,小世界圖

十一 矩陣空間&#xff0c;秩1矩陣&#xff0c;小世界圖 1. 矩陣空間交集 和 和集 2. 所有解空間3. r 1 r1 r1的矩陣4. 題目5. 小世界圖 空間&#xff1a;組成空間的元素的線性組合都在這個空間中。 1. 矩陣空間 舉例&#xff1a;矩陣空間&#xff08; M M M 所有3x3的矩陣&…

【網絡安全 | 滲透測試】GraphQL精講一:基礎知識

未經許可,不得轉載, 文章目錄 GraphQL 定義GraphQL 工作原理GraphQL 模式GraphQL 查詢GraphQL 變更(Mutations)查詢(Queries)和變更(Mutations)的組成部分字段(Fields)參數(Arguments)變量別名(Aliases)片段(Fragments)訂閱(Subscriptions)自省(Introspecti…

關于虛擬環境中遇到的bug

conda和cmd介紹 介紹 Conda 概述&#xff1a; Conda是一個開源包管理系統和環境管理系統&#xff0c;尤其適用于Python和R語言的開發環境。它允許用戶創建獨立的虛擬環境&#xff0c;方便地管理依賴包和軟件版本。 特點&#xff1a; 環境管理&#xff1a;可以創建、導入、導…

基于nginx的灰度發布解決方案

Nginx 在灰度發布中可以看作是一個精確的流量調度員&#xff0c;它充當著客戶端與后端服務器之間的中介。通過配置好的規則&#xff0c;Nginx 會將用戶請求智能地引導到不同版本的服務上。這樣&#xff0c;Nginx 可以根據具體需求靈活地分配流量&#xff0c;確保新版本逐步推向…

網絡安全法與等級保護 PPT 精華匯總

資源描述 本資源文件為《網絡安全法與等級保護》的PPT精華匯總&#xff0c;內容涵蓋了網絡安全法與等級保護的總體框架及相關標準規范。該PPT詳細介紹了網絡安全法與等級保護的各個章節和條款&#xff0c;并提供了基礎類和應用類的相關標準文件&#xff0c;幫助讀者全面了解和…

uni-app開發安卓和iOS 打包流程(云打包)

首先講一下安卓打包的流程,之后再說ios。打包安卓和iOS打包的流程有些不同,安卓打包相對來說比較簡單,而iOS打包需要更多的準備工作,如申請開發者賬號、生成證書等。 一、安卓打包 1、安卓打包直接在window電腦上就可以操作,打開hbuilderx,找到你的項目選中,然后點擊發…

攝像頭應用編程(四):ARM Linux LCD實時預覽UVC攝像頭畫面

文章目錄 1、前言2、環境介紹3、步驟4、應用程序編寫4.1、lcd初始化4.2、攝像頭初始化4.3、jpeg解碼4.4、開啟攝像頭4.5、完整的程序如下 5、測試5.1、編譯應用程序5.2、運行應用程序 6、總結 1、前言 本次應用程序主要針對支持MJPEG格式輸出的UVC攝像頭。 2、環境介紹 rk35…

藍橋與力扣刷題(藍橋 k倍區間)

題目&#xff1a;給定一個長度為 N 的數列&#xff0c;A1,A2,?AN?&#xff0c;如果其中一段連續的子序列 Ai,Ai1,?Aj( i≤j ) 之和是 K 的倍數&#xff0c;我們就稱這個區間[i,j] 是 K 倍區間。 你能求出數列中總共有多少個 K 倍區間嗎&#xff1f; 輸入描述 第一行包含兩…

json介紹、python數據和json數據的相互轉換

目錄 一 json介紹 json是什么&#xff1f; 用處 Json 和 XML 對比 各語言對Json的支持情況 Json規范詳解 二 python數據和json數據的相互轉換 dumps() : 轉換成json loads(): 轉換成python數據 總結 一 json介紹 json是什么&#xff1f; 實質上是一條字符串 是一種…

PAT乙級真題 / 知識點(1)

引言&#xff1a; 起初&#xff0c;報PAT是伙伴推薦。但在報名路途中&#xff0c;有朋友說&#xff0c;花時間到這上面不值得&#xff0c;還有學長說沒聽過&#xff0c;野雞杯。 我一笑而過&#xff0c;我可能就是偏執&#xff0c;我就是想報。隨著刷真題&#xff0c;我的基礎…

單細胞分析(20)——inferCNV分析

InferCNV分析筆記 1. 分析目標 InferCNV&#xff08;Inference of Copy Number Variations&#xff09;是一種基于單細胞轉錄組數據推斷**拷貝數變異&#xff08;CNV&#xff09;**的方法&#xff0c;推測其基因組變異情況。 2. 數據準備 2.1 載入數據 library(Seurat) set…

C++:多態與虛函數

1.虛函數&#xff0c;在函數前加virtual即可。有虛函數時&#xff0c;父類指針指向父類對象時就會使用父類的成員&#xff0c;指向子類對象時就可以使用子類成員&#xff0c;進而我們引入了多態的概念。 2.多態&#xff1a;父類指針指向子類的對象&#xff0c;通過父類指針調用…

WSL下使用git克隆失敗解決

WSL默認nat模式&#xff0c;別動了防火墻放行&#xff0c;見圖1git導入[bash1]&#xff0c;ip為你wsl上linxu通過ifconfig獲取的本機ip&#xff0c;端口對好某alcsh軟件開啟tun模式【經過測試&#xff0c;不開也行】應該成了&#xff0c;如果不行&#xff0c;修改.wslconfig為下…

開放鴻蒙OpenHarmony 5.0.0 Release 兼容性測試實戰經驗分享

OpenHarmony 5.0版本的發布時間是2024年12月20日至21日。這個版本帶來了許多新特性和改進。現在5.0出了兩個release 版本&#xff0c;分別是5.0.0和5.0.1。 就在5.0版本發布不到2周的時間內&#xff0c;2025年01月01日起&#xff0c;不支持新產品基于老分支&#xff08;OpenHar…

C++中explicit關鍵字的含義以及用法

在C中&#xff0c;explicit關鍵字用于修飾構造函數和轉換運算符&#xff08;C11起&#xff09;&#xff0c;防止編譯器進行隱式類型轉換&#xff0c;要求必須顯式調用構造函數或轉換操作。以下是其核心用法和示例&#xff1a; 1. 修飾構造函數 用途 禁止隱式構造對象&#xf…

Oracle OCP認證考試考點詳解083系列01

題記&#xff1a; 本系列主要講解Oracle OCP認證考試考點&#xff08;題目&#xff09;&#xff0c;適用于19C/21C,跟著學OCP考試必過。 1. 第1題&#xff1a; 題目 解析及答案&#xff1a; 關于自動工作量存儲庫&#xff08;AWR&#xff09;快照&#xff0c;以下哪三個選項…

從DNS到TCP:DNS解析流程和瀏覽器輸入域名訪問流程

1 DNS 解析流程 1.1 什么是DNS域名解析 在生活中我們會經常遇到域名&#xff0c;比如說CSDN的域名www.csdn.net&#xff0c;百度的域名www.baidu.com,我們也會碰到IP&#xff0c;現在目前有的是IPV4&#xff0c;IPV6。那這兩個有什么區別呢&#xff1f;IP地址是互聯網上計算機…

《2025軟件測試工程師面試》接口測試篇

基礎概念 什么是接口測試? 接口測試是測試系統組件間接口的一種測試,主要用于檢測外部系統和內部系統之間以及各個子系統之間的交互點。測試的重點是檢查數據的交換、傳遞和控制管理的過程,以及系統間的相互邏輯依賴關系等。 接口測試的優勢是什么? 接口測試具有規范性與擴…

【PHP腳本語言詳解】為什么直接訪問PHP文件會顯示空白?從錯誤示例到正確執行!

前言 作為一名開發者&#xff0c;你是否曾經遇到過這樣的問題&#xff1a;寫了一個PHP腳本&#xff0c;放到服務器根目錄后&#xff0c;直接通過file:///路徑訪問卻顯示空白頁面&#xff1f;而換成http://localhost卻能正常顯示&#xff1f;這篇文章將帶你深入理解PHP腳本語言…

word轉換為pdf后圖片失真解決辦法、高質量PDF轉換方法

1、安裝Adobe Acrobat Pro DC 自行安裝 2、配置Acrobat PDFMaker &#xff08;1&#xff09;點擊word選項卡上的Acrobat插件&#xff0c;&#xff08;2&#xff09;點擊“首選項”按鈕&#xff0c;&#xff08;3&#xff09;點擊“高級配置”按鈕&#xff08;4&#xff09;點…