圖論學習 c++Ford-Fulkerson 方法

Ford-Fulkerson算法是用于求解最大流問題的一種經典算法。其核心思想是通過不斷尋找增廣路徑來增加流量,直到找不到增廣路徑為止。每次找到一條增廣路徑,就增加相應的流量,更新殘余網絡。簡單來說就是Ford-Fulkerson算法的工作過程,即不斷尋找增廣路徑并增加流量,直到無法找到增廣路徑為止。

算法步驟

  1. 初始化: 將所有邊的流量初始化為0。
  2. 尋找增廣路徑: 使用深度優先搜索(DFS)或廣度優先搜索(BFS)在殘余網絡中尋找從源點到匯點的增廣路徑。
  3. 增廣路徑上增加流量: 在找到的增廣路徑上增加可以增加的最小流量。
  4. 更新殘余網絡: 根據增廣路徑上的流量調整殘余網絡。
  5. 重復步驟2-4,直到找不到增廣路徑為止。

以一個簡單的例子來演示Ford-Fulkerson算法的執行過程。

假設有一個流網絡如下:

  源點 (S)/   \
10     5
/       \
A        B
\       /5   10\   /C|10|匯點 (T)

其中每條邊的數字表示容量。

步驟1:初始化

  • 所有邊的流量初始化為0。

步驟2:尋找增廣路徑

  • 使用DFS或BFS從源點S尋找增廣路徑。假設我們使用DFS找到路徑S -> A -> C -> T,路徑上的容量為10,最小容量為5。

步驟3:增廣路徑上增加流量

  • 增加流量5。路徑S -> A -> C -> T上各邊的流量增加5。
  • 更新后的流量:
    • S -> A 流量為5,剩余容量為5。
    • A -> C 流量為5,剩余容量為0。
    • C -> T 流量為5,剩余容量為5。

步驟4:更新殘余網絡

  • 根據增廣路徑上的流量調整殘余網絡。增加逆向邊用于表示可以回退的流量。
    • 增加逆向邊A -> S,容量為5,流量為0。
    • 增加逆向邊C -> A,容量為5,流量為0。
    • 增加逆向邊T -> C,容量為5,流量為0。

步驟2:尋找增廣路徑(繼續)

  • 繼續尋找另一條增廣路徑。假設找到路徑S -> B -> C -> T,路徑上的容量為10,最小容量為5。

步驟3:增廣路徑上增加流量

  • 增加流量5。路徑S -> B -> C -> T上各邊的流量增加5。
  • 更新后的流量:
    • S -> B 流量為5,剩余容量為0。
    • B -> C 流量為5,剩余容量為5。
    • C -> T 流量為10,剩余容量為0。

步驟4:更新殘余網絡

  • 根據增廣路徑上的流量調整殘余網絡。增加逆向邊用于表示可以回退的流量。
    • 增加逆向邊B -> S,容量為5,流量為0。
    • 增加逆向邊C -> B,容量為5,流量為0。
    • 增加逆向邊T -> C,容量為5,流量為0。

步驟2:尋找增廣路徑(結束)

  • 繼續尋找增廣路徑,發現沒有增廣路徑了。

結果

  • 最大流量為10。
#include <iostream>     // 包含輸入輸出流的頭文件
#include <vector>       // 包含向量容器的頭文件
#include <queue>        // 包含隊列容器的頭文件
#include <climits>      // 包含INT_MAX定義的頭文件
#include <cstring>      // 包含memset函數的頭文件using namespace std;    // 使用標準命名空間class FordFulkerson {int V; // 頂點數量vector<vector<int>> capacity; // 容量矩陣vector<vector<int>> adj; // 鄰接表// 廣度優先搜索(BFS)函數,用于在殘余網絡中尋找增廣路徑bool bfs(vector<int>& parent, int s, int t) {vector<bool> visited(V, false); // 訪問標記數組,初始化為未訪問queue<int> q; // BFS隊列q.push(s); // 源點入隊visited[s] = true; // 標記源點為已訪問parent[s] = -1; // 源點沒有父節點while (!q.empty()) { // 當隊列不為空時int u = q.front(); // 取出隊首元素q.pop(); // 隊首元素出隊for (int v : adj[u]) { // 遍歷鄰接表中的所有鄰接節點if (!visited[v] && capacity[u][v] > 0) { // 如果節點未訪問且有剩余容量if (v == t) { // 如果找到匯點parent[v] = u; // 記錄父節點return true; // 返回找到增廣路徑}q.push(v); // 將節點入隊parent[v] = u; // 記錄父節點visited[v] = true; // 標記節點為已訪問}}}return false; // 如果沒有找到增廣路徑,返回false}public:// 構造函數,初始化頂點數量、容量矩陣和鄰接表FordFulkerson(int V) : V(V), capacity(V, vector<int>(V, 0)), adj(V) {}// 添加邊及其容量void addEdge(int u, int v, int cap) {capacity[u][v] = cap; // 設置容量adj[u].push_back(v); // 添加鄰接點adj[v].push_back(u); // 添加反向邊的鄰接點}// 計算最大流量int maxFlow(int s, int t) {int max_flow = 0; // 初始化最大流量為0vector<int> parent(V); // 用于記錄增廣路徑中的父節點while (bfs(parent, s, t)) { // 當找到增廣路徑時int path_flow = INT_MAX; // 初始化路徑流量為無窮大// 計算增廣路徑中的最小流量for (int v = t; v != s; v = parent[v]) {int u = parent[v];path_flow = min(path_flow, capacity[u][v]);}// 更新殘余網絡中的容量for (int v = t; v != s; v = parent[v]) {int u = parent[v];capacity[u][v] -= path_flow;capacity[v][u] += path_flow;}// 增加總流量max_flow += path_flow;}return max_flow; // 返回最大流量}
};int main() {int V = 6; // 頂點數量 (包括源點和匯點)FordFulkerson graph(V); // 創建一個FordFulkerson對象// 添加邊和對應的容量graph.addEdge(0, 1, 10); // S -> A 容量 10graph.addEdge(0, 2, 5);  // S -> B 容量 5graph.addEdge(1, 3, 5);  // A -> C 容量 5graph.addEdge(2, 3, 10); // B -> C 容量 10graph.addEdge(3, 5, 10); // C -> T 容量 10int source = 0; // 源點 Sint sink = 5;   // 匯點 T// 計算并輸出最大流量cout << "最大流量: " << graph.maxFlow(source, sink) << endl;return 0;
}

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

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

相關文章

【探索Linux】P.37(傳輸層 —— TCP協議通信機制 | 確認應答(ACK)機制 | 超時重傳機制)

閱讀導航 引言一、確認應答(ACK)機制1. 成功接收2. 過程中存在丟包3. 引入序列號&#xff08;1&#xff09;序列號的定義&#xff08;2&#xff09;序列號的作用&#xff08;3&#xff09;序列號的工作原理&#xff08;4&#xff09;序列號和確認應答號 二、超時重傳機制1. 超時…

基于Java的壁紙網站設計與實現

&#x1f497;博主介紹&#x1f497;&#xff1a;?在職Java研發工程師、專注于程序設計、源碼分享、技術交流、專注于Java技術領域和畢業設計? 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的老師 Wechat / QQ 名片 :) Java精品實戰案例《700套》 2025最新畢業設計選題推薦…

ERP的模塊說明

ERP的模塊&#xff1a;物料管理、銷售管理、生產管理)、財務管理、質量管理、人力資源管理、項目管理、倉儲管理(WMS)、供應商管理(SRM)等功能模塊 ERP流程通常涉及以下幾個關鍵步驟&#xff1a; 制定生產計劃&#xff1a;這是ERP流程的第一步&#xff0c;需要根據產品預測和訂…

Oracle中http的post的用法和例子

在Oracle數據庫中&#xff0c;直接執行HTTP POST請求并不是數據庫核心功能的一部分。但是&#xff0c;你可以通過Oracle的PL/SQL程序結合一些額外的工具或庫來實現這一功能。 以下是一個使用Oracle UTL_HTTP包&#xff08;Oracle提供的用于HTTP通信的PL/SQL包&#xff09;來發…

nftables(1)基本原理

簡介 nftables 是 Linux 內核中用于數據包分類的現代框架&#xff0c;用來替代舊的 iptables&#xff08;包括 ip6tables, arptables, ebtables 等&#xff0c;統稱為 xtables&#xff09;架構。nftables 提供了更強大、更靈活以及更易于管理的規則集配置方式&#xff0c;使得…

【java計算機畢設】辦公用品管理系統MySQL ssm JSP maven項目設計代碼源碼+文檔 前后端一體

1項目功能 【java計算機畢設】辦公用品管理系統MySQL ssm JSP maven項目設計代碼源碼文檔 前后端一體 2項目介紹 系統功能&#xff1a; 辦公用品管理系統包括管理員、用戶倆種角色。 管理員功能包括個人中心模塊用于修改個人信息和密碼、用戶管理、用品分類管理、用品信息管理…

springcloud+vue項目,controller層接口返回json數據,前端可以接收到數據,但瀏覽器“F12-->網絡-->響應“顯示為空的問題處理

1.顯示為空的場景 SharetekR(access_tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJQQzoxODA1ODA4ODc1MjUwMTIyNzUyIiwicm5TdHIiOiJrZEoxV05CV3NBSUdYb05TbktSU3kzOGNuSnk3c3FRTSIsInVzZXJJZCI6MTgwNTgwODg3NTI1MDEyMjc1MiwidXNlck5h…

grpc-go客戶端接口添加

【1】 proto相關文件同服務端&#xff0c;如已經生成&#xff0c;可以直接使用服務端的文件&#xff08;包&#xff09; 【2】新建一個目錄“WHG_CLIENT”&#xff0c;目錄下新建一個main.go文件 package mainimport ("context""log""grpc-go-maste…

Kafka系列之SpringBoot集成Kafka

本文介紹如何在springboot項目中集成kafka收發message。 pom依賴 springboot相關的依賴我們就不提了&#xff0c;和kafka相關的只依賴一個spring-kafka集成包 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka<…

STM32F1+HAL庫+FreeTOTS學習5——內核中斷管理及中斷控制函數

STM32F1HAL庫FreeTOTS學習5——中斷管理和臨界段代碼保護 中斷簡介中斷優先級寄存器拓展FreeRTOS中PendSV和Systick中斷優先級配置三個中斷屏蔽寄存器FreeRTOS中斷管理函數代碼驗證 上一期我們學習了FreeRTOS中任務掛起與恢復&#xff0c;在中斷服務程序中恢復任務過程中&#…

[Redis]哨兵機制

哨兵機制概念 在傳統主從復制機制中&#xff0c;會存在一些問題&#xff1a; 1. 主節點發生故障時&#xff0c;進行主備切換的過程是復雜的&#xff0c;需要人工參與&#xff0c;導致故障恢復時間無法保障。 2. 主節點可以將讀壓力分散出去&#xff0c;但寫壓力/存儲壓力是無法…

印章誰在管、誰用了、用在哪?契約鎖讓您打開手機一看便知

“印章都交給誰在管”、“哪些人能用”、“都有哪些業務在用”…這些既是管理者最關心的印章問題也是影響印章安全的關鍵要素。但是公司旗下分子公司那么多&#xff0c;各類公章、法人章、財務章、合同章一大堆&#xff0c;想“問”明白很難。 契約鎖電子簽及印控平臺推出“印章…

14-11 2024 年的 13 個 AI 趨勢

2024 年的 13 個 AI 趨勢 人工智能對環境的影響和平人工智能人工智能支持的問題解決和決策針對人工智能公司的訴訟2024 年美國總統大選與人工智能威脅人工智能、網絡犯罪和社會工程威脅人工智能治療孤獨與對人工智能的情感依賴人工智能影響者中國爭奪人工智能霸主地位人工智能…

一句話回答的前端面試題

該篇文章為一句話的答案&#xff0c;想看更詳細的面試題請看這篇>《前端面試題》 原型鏈&#xff1a; 實例與原型的鏈條&#xff0c;原型是prototype&#xff0c;鏈是__proto__&#xff0c;每個函數有一個原型對象&#xff0c;函數在創建時有一個默認屬性 prototype&#x…

YOLOv10全網最新創新點改進系列:融合GSConv+Slim Neck,雙改進、雙增強,替換特征融合層實現, 輕量化漲點改進策略,有效漲點神器!

YOLOv10全網最新創新點改進系列&#xff1a;融合GSConvSlim Neck&#xff0c;雙改進、雙增強&#xff0c;替換特征融合層實現&#xff0c; 輕量化漲點改進策略&#xff0c;有效漲點神器&#xff01; 所有改進代碼均經過實驗測試跑通&#xff01;截止發稿時YOLOv10已改進40&…

【數據結構】06.棧隊列

一、棧 1.1棧的概念及結構 棧&#xff1a;一種特殊的線性表&#xff0c;其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂&#xff0c;另一端稱為棧底。棧中的數據元素遵守后進先出LIFO&#xff08;Last In First Out)的原則。 壓棧&#…

FPGA就業方向以及主要工作

FPGA&#xff08;Field-Programmable Gate Array&#xff09;作為可編程邏輯器件&#xff0c;在多個行業和領域中都有廣泛的應用。具備FPGA技能的專業人士可以在多個方向上找到就業機會&#xff0c;以下是FPGA主要的就業方向及其對應的主要工作職責&#xff1a; 通信行業 職位…

LangChain終極內幕指南,學會langchain就看它了

1.概述 在人工智能迅速演進的時代&#xff0c;諸如Open AI的ChatGPT和Google的Bard等大型語言模型(LLMs)正徹底改變我們與技術互動的方式。這些技術巨頭和SaaS公司正在競相利用LLMs的威力&#xff0c;創造更為智能和實用的應用程序。 然而&#xff0c;真正的變革并非僅僅停留…

低壓電工精選歷年真題附答案

1.當電壓為5V時&#xff0c;導體的電阻值為5歐&#xff0c;那么當電阻兩端電壓為2V時&#xff0c;導體的電阻值為()歐。[單選題] A 、10B、5(正確答案) C、2 2.當電氣火災發生時&#xff0c;應首先切斷電源再滅火&#xff0c;但當電源無法切斷時&#xff0c;只能帶電滅火&…

Finding and exploting an unused API endpoint

Using 0$ account buy a piece of lether priced at $133 1、嘗試訪問api接口 大概率可能訪問不到,但是可以嘗試訪問下 /api/swagger/v1 /openapi.json 2、頁面功能點尋找 api send to Repeter 3、Find Supported HTTP請求 POST方法測試 通過測試得知支持GET方法和PATC…