当前位置: 首页 > news >正文

图论 | 网络流的基本概念

文章目录

    • 流网路
    • 残留网络
    • 增广路径
    • 最大流最小割定理
    • 最大流
      • Edmonds-Karp 算法
        • 算法步骤
        • 程序代码
        • 时间复杂度

流网路

流网络: G = ( V , E ) G = (V, E) G=(V,E)

在这里插入图片描述

  • 有向图,不考虑反向边
  • s:源点
  • t:汇点
  • c ( u , v ) c(u, v) c(u,v):边的最大容量
  • 可行流 f f f
    • 容量限制: 0 ≤ f ( u , v ) ≤ c ( u , v ) 0 \leq f(u, v) \leq c(u, v) 0f(u,v)c(u,v)
    • 流量守恒:除了源点和汇点,所有点满足 流入 = 流出 流入 = 流出 流入=流出
  • ∣ f ∣ |f| f:可行流的流量,即从源点流向汇点的速率。一种通用的解释是 从源点流出的流量 − 流入源点的流量 从源点流出的流量 - 流入源点的流量 从源点流出的流量流入源点的流量
  • 最大流:最大可行流

残留网络

残留网络定义:一个可行流流网络 f f f 对应一个残留网络 G f G_f Gf

  • 点集:与原图的点集一样 V f = V V_f = V Vf=V
  • 边集:不仅包含原图的边,同时包含所有边的方向边,即 E f = E 和 E 中的所有反向边 E_f = E 和 E中的所有反向边 Ef=EE中的所有反向边
  • 边的容量: c f ( u , v ) c_f(u, v) cf(u,v)
    • 原图中的边:剩下的容量,即 c ( u , v ) − f ( u , v ) c(u, v) - f(u, v) c(u,v)f(u,v)
    • 反向边:可以退回的流量,即 f ( v , u ) f(v, u) f(v,u)

重要结论:原网络的可行流 f f f 加上可行流对应的残留网络 G f G_f Gf,也是一个可行流

  • 对应边相加:若方向同则相加;若反向反则相减
  • 结论: ∣ f + f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣ |f + f'| = |f| + |f'| f+f=f+f
  • 进一步,若残留网络没有可行流,那么原网络的可行流就一定是最大流

增广路径

在残留网络里,如果沿着容量大于 0 的边走,能走到汇点,则这条路径叫做增广路径

  • 若存在一个增广路径,根据 ∣ f + f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣ |f + f'| = |f| + |f'| f+f=f+f,原来的可行流一定不是最大流
  • 若不存在增广路径,我们可以得出当前可行流就是最大流

将点集 V 分成 S 和 T 两个子集

  • 分割要满足 S ∪ T = V , S ∩ T = ∅ S ∪ T = V, S ∩ T = \emptyset ST=VST=
  • 点集不一定连通

割的容量: c ( S , T ) = ∑ u ∈ S ∑ v ∈ T c ( u , v ) c(S, T) = \sum_{u ∈ S} \sum_{v ∈ T} c(u, v) c(S,T)=uSvTc(u,v)

  • 最小割:最小割的容量
  • 割的容量不考虑反向边

割的流量: f ( S , T ) = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ u ∈ T ∑ v ∈ S f ( u , v ) f(S, T) = \sum_{u ∈ S} \sum_{v ∈ T} f(u, v) - \sum_{u ∈ T} \sum_{v ∈ S} f(u, v) f(S,T)=uSvTf(u,v)uTvSf(u,v)

  • 流过去的流量减去流过来的流量
  • 割的流量考虑反向边

重要性质:

  • 对于任意一个割,割的流量一定小于等于割的容量,即 f ( S , T ) ≤ c ( S , T ) f(S, T) \leq c(S, T) f(S,T)c(S,T)

  • 割的流量等于原流网络的流量,即 f ( S , T ) = ∣ f ∣ f(S,T) = |f| f(S,T)=f

  • f ( X , Y ) = − f ( Y , X ) f(X, Y) = -f(Y, X) f(X,Y)=f(Y,X)

  • f ( Z , X ∪ Y ) = f ( Z , X ) + f ( Z , Y ) f(Z, X ∪ Y) = f(Z, X) + f(Z, Y) f(Z,XY)=f(Z,X)+f(Z,Y)

  • f ( X ∪ Y , Z ) = f ( X , Z ) + f ( Y , Z ) f(X ∪ Y, Z) = f(X, Z) + f(Y, Z) f(XY,Z)=f(X,Z)+f(Y,Z)

最大流最小割定理

以下三个条件是等价的

  1. 可行流 f f f 是最大流
  2. 可行流 f f f 的残留网络中不存在增广路
  3. 存在某个割 [ S , T ] [S, T] [S,T] ∣ f ∣ = c ( S , T ) |f| = c(S, T) f=c(S,T)

最大流

Edmonds-Karp 算法

算法步骤

维护流网络的残留网络,不断进行以下流程:

  1. 找一条增广路 f ′ f' f:可以用 BFS 进行搜索
  2. 更新残留网络 G f → G f + f ′ G_f → G_{f + f'} GfGf+f
程序代码
#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;const int N = 1010, M = 20020, INF = 1e8;// 邻接表存储残留网络
// 正向边和反向边成对存在,正向边的下标异或上1得到方向边的下标
int n, m, S, T;
int h[N], e[M], f[M], ne[M], idx;  // f表示容量
int q[N], d[N], pre[N];
bool st[N];  // 避免重复搜索void add(int a, int b, int c)
{// 正向边 e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;// 反向边,初始容量为0e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}// bfs找增广路
bool bfs()
{int hh = 0, tt = 0;memset(st, false, sizeof(st));q[0] = S, st[S] = true, d[S] = INF;while(hh <= tt) {// 从队列中弹出一个元素进行BFSint t = q[hh++];for(int i = h[t]; ~i; i = ne[i]) {// 节点t的临接边i的下一节点verint ver = e[i];// 没遍历过且边i的容量不为0if( !st[ver] && f[i] ) {st[ver] = true;// 流到节点ver的流量为流到t的流量和边i容量的最小值d[ver] = min(d[t], f[i]);// 记录节点ver前驱边的编号pre[ver] = i;if(ver == T)  return true;// ver入队q[++tt] = ver;}}}return false;
}// EK 算法
int EK()
{int r = 0;while( bfs() ) {// 加上增广路的流量r += d[T];// 更新残留网络for(int i = T; i != S; i = e[pre[i] ^ 1]) {// 正向边更新f[pre[i]] -= d[T];// 反向边更新f[pre[i] ^ 1] += d[T];}}return r;
}int main()
{// 点数、边数、源点、汇点cin >> n >> m >> S >> T;// 初始化邻接表memset(h, -1, sizeof(h));while( m-- ) {int a, b, c;// 边ab的容量为ccin >> a >> b >> c;add(a, b, c);}cout << EK() << endl;return 0;
}
时间复杂度

O ( V E 2 ) O(VE^2) O(VE2)

相关文章:

图论 | 网络流的基本概念

文章目录 流网路残留网络增广路径割最大流最小割定理最大流Edmonds-Karp 算法算法步骤程序代码时间复杂度 流网路 流网络&#xff1a; G ( V , E ) G (V, E) G(V,E) 有向图&#xff0c;不考虑反向边s&#xff1a;源点t&#xff1a;汇点 c ( u , v ) c(u, v) c(u,v)&#xff…...

【音视频 | AAC】AAC音频编码详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

redis基本用法学习(C#调用NRedisStack操作redis)

redis官网文档中推荐C#中使用NRedisStack包连接并操作redis&#xff0c;本文学习C#调用NRedisStack操作redis的基本方式。   新建Winform项目&#xff0c;在Nuget包管理器中搜索并安装NRedisStack包&#xff0c;如下图所示&#xff1a; 主要调用StackExchange.Redis命名空间下…...

[CVPR 2023:3D Gaussian Splatting:实时的神经场渲染]

文章目录 前言小结 原文地址&#xff1a;https://blog.csdn.net/qq_45752541/article/details/132854115 前言 mesh 和点是最常见的3D场景表示&#xff0c;因为它们是显式的&#xff0c;非常适合于快速的基于GPU/CUDA的栅格化。相比之下&#xff0c;最近的神经辐射场&#xf…...

【SpringBoot快速入门】(4)SpringBoot项目案例代码示例

目录 1 创建工程3 配置文件4 静态资源 之前我们已经学习的Spring、SpringMVC、Mabatis、Maven&#xff0c;详细讲解了Spring、SpringMVC、Mabatis整合SSM的方案和案例&#xff0c;上一节我们学习了SpringBoot的开发步骤、工程构建方法以及工程的快速启动&#xff0c;从这一节开…...

Linux服务器 部署飞书信息发送服务

项目介绍&#xff1a; 飞书信息发送服务是指将飞书信息发送服务部署到一个Linux服务器上。飞书是一款企业级的即时通讯和协作工具&#xff0c;支持发送消息给飞书的功能。通过部署飞书信息发送服务&#xff0c;可以方便内网发送信息给外网飞书。 项目代码结构展示&#xff1a; …...

用C#也能做机器学习?

前言✨ 说到机器学习&#xff0c;大家可能都不陌生&#xff0c;但是用C#来做机器学习&#xff0c;可能很多人还第一次听说。其实在C#中基于ML.NET也是可以做机器学习的&#xff0c;这种方式比较适合.NET程序员在项目中集成机器学习模型&#xff0c;不太适合专门学习机器学习&a…...

Python PDF格式转PPT格式

要将PDF文件转换为PPT&#xff0c;我实在python3.9 环境下转成功的&#xff0c;python3.11不行。 需要 pip install PyMuPDF代码说话 # -*- coding: utf-8 -*-""" author: 赫凯 software: PyCharm file: xxx.py time: 2023/12/21 11:20 """im…...

搭建知识付费平台?明理信息科技为你提供全程解决方案

明理信息科技saas知识付费平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和维护…...

漫谈UNIX、Linux、UNIX-Like

漫谈UNIX、Linux、UNIX-Like 使用了这么多年Redhat、Ubuntu等Linux、Windows、Solaris操作系统&#xff0c;你是否对UNIX、Unix-Like&#xff08;类UNIX&#xff09;还是不太清楚&#xff1f;我以前一直认为Unix-Like就等于Linux。其实&#xff0c;由UNIX派生出来而没有取得UN…...

Netty Review - Netty与Protostuff:打造高效的网络通信

文章目录 概念PrePomServer & ClientProtostuffUtil 解读测试小结 概念 Pre 每日一博 - Protobuf vs. Protostuff&#xff1a;性能、易用性和适用场景分析 Pom <dependency><groupId>com.dyuproject.protostuff</groupId><artifactId>protostuff-…...

在ClickHouse数据库中启用预测功能

在这篇博文中&#xff0c;我们将介绍如何将机器学习支持的预测功能与 ClickHouse 数据库集成。ClickHouse 是一个快速、开源、面向列的 SQL 数据库&#xff0c;对于数据分析和实时分析非常有用。该项目由 ClickHouse&#xff0c; Inc. 维护和支持。我们将探索它在需要数据准备以…...

目标检测YOLO实战应用案例100讲-树上果实识别与跟踪计数(续)

目录 3.2 损失函数优化 3.3 实验过程 3.3.1 果实图像采集 3.3.2 数据扩增...

Docker 文件和卷 权限拒绝

一 创作背景 再复制Docker影像文件或访问Docker容器内已安装卷上的文件时我们常常会遇到&#xff1a;“权限被拒绝”的错误&#xff0c;在此&#xff0c;您将了解到为什么会出现“权限被拒绝”的错误以及如何解决这个问题。 二 目的 在深入探讨 Docker 容器中的 Permission De…...

Appium Server 启动失败常见原因及解决办法

Error: listen EADDRINUSE: address already in use 0.0.0.0:4723 如下图&#xff1a; 错误原因&#xff1a;Appium 默认的4723端口被占用 解决办法&#xff1a; 出现该提示&#xff0c;有可能是 Appium Server 已启动&#xff0c;关闭已经启动的 Appium Server 即可。472…...

将Abp默认事件总线改造为分布式事件总线

文章目录 原理创建分布式事件总线实现自动订阅和事件转发 使用启动Redis服务配置传递Abp默认事件传递自定义事件 项目地址 原理 本地事件总线是通过Ioc容器来实现的。 IEventBus接口定义了事件总线的基本功能&#xff0c;如注册事件、取消注册事件、触发事件等。 Abp.Events…...

Jupyter Notebook修改默认工作目录

1、参考修改Jupyter Notebook的默认工作目录_jupyter文件路径-CSDN博客修改配置文件 2.在上述博客内容的基础上&#xff0c;这里不是删除【%USERPROFILE%】而是把这个地方替换为所要设置的工作目录路径&#xff0c; 3.【起始位置】也可以更改为所要设置的工作目录路径&#x…...

高校/企业如何去做数据挖掘呢?

随着近年来人工智能及大数据、云计算进入爆发时期&#xff0c;依托三者进行的数据分析、数据挖掘服务已逐渐成为各行业进行产业升级的载体&#xff0c;缓慢渗透进我们的工作和生活&#xff0c;成为新时代升级版的智能“大案牍术”。 那么对于多数企业来说&#xff0c;如何做数据…...

数据仓库-数据治理小厂实践

一、简介 数据治理贯穿数仓中数据的整个生命周期&#xff0c;从数据的产生、加载、清洗、计算&#xff0c;再到数据展示、应用&#xff0c;每个阶段都需要对数据进行治理&#xff0c;像有些比较大的企业都是有自己的数据治理平台或者会开发一些便捷的平台&#xff0c;对于没有平…...

【C++多线程编程】(五)之 线程生命周期管理join() 与 detach()

在C中&#xff0c;std::thread 类用于创建和管理线程。std::thread 提供了两种主要的方法来控制线程的生命周期&#xff1a;join 和 detach。 detach方式&#xff0c;启动的线程自主在后台运行&#xff0c;当前的代码继续往下执行&#xff0c;不等待新线程结束。join方式&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...