图论学习 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.mzph.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…