首页 > 其他分享 >网络流小记

网络流小记

时间:2024-04-24 13:23:16浏览次数:32  
标签:int cap flow 网络 dep edges 小记

基本定义:

  • 网络:一张有向图。

  • 流量:经过一条边的流的大小,一条边 \((u,v)\) 的流量记为 \(flow(u,v)\), 一个网络的流量定义为 \(∑f(s,x)\)。

  • 容量:一条边的流量上限,一条边 \((u,v)\) 的容量记为 \(cap(u,v)\)。

  • 费用:经过一条边单位流量的所需费用,一条边 \((u,v)\) 的费用记为 \(cost(u,v)\)。

  • 源点:所有流的起始点, 记为 \(s\)。

  • 汇点:所有流的终止点,记为 \(t\)。

  • 割:是网络的一个划分, 一个割 {\(S, T\)} 的容量定义为 \(||S, T|| = \sum_{u \in S} \sum_{v \in T} cap(u, v)\)。

  • 残量网络:每条边剩余可走的流量组成的网络。

网络流的性质:

  1. 斜对称性:\(flow(u,v) = -flow(v,u)\)

  2. 流量守恒:\(\sum_{u \ne x, t\ne y} flow(u, x) = \sum flow(y,u)\)

  3. 容量限制: \(flow(u,v) \le cap(u,v)\)

一些定理:

增广路定理

增广路:在残量网络中的一条 \(s\) 到 \(t\) 的路径,满足路径上的残量均大于 \(0\)。

一个流为最大流当且仅当网络中没有增广路。

最大流最小割定理:

对于任意网络,最大流 \(f\) 和最小割 \(\{S, T\}\) 总是满足 \(|f| = ||S, T||\)。

证明可见 OI-WIKI

EK 算法:

对于求一张图的最大流,我们考虑引入反向边的概念。

由上面的定理,我们可以得到以下算法:

  1. 在残量网络上找一条增广路,将这条路径上的流大小记为 \(flow\)

  2. 将路径上的所有边加上 \(flow\),反向边减掉 \(flow\)。

注意:增广路可以经过反向边!

经过反向边相当于做返回操作,这也是 EK 算法的关键之处。

时间复杂度 \(O(nm^2)\)。

Dinic 算法:

考虑优化上面的算法,我们将原图进行分层,从源点开始,按于源点的距离分层。

做完分层后,像 EK 一样在分层图中找增广路,但是一次可以找多条。

前者用 bfs 实现,后者用 dfs 实现。

code:

namespace Dinic{
	struct edge{
		int v, next, cap, flow;
	}edges[M << 1];
	int head[N], idx = 1;
	int cur[N], dep[N];
	int maxflow = 0;
	
	void add_edge(int u, int v, int cap){
		edges[++idx] = {v, head[u], cap, 0};
		head[u] = idx;
	}
	bool bfs(){
		queue<int>Q;
		memset(dep, 0, sizeof dep);
		dep[s] = 1, Q.push(s);
		while(!Q.empty()){
			int u = Q.front(); Q.pop();
			for(int i = head[u]; i; i = edges[i].next){
				int v = edges[i].v;
				if(!dep[v] && (edges[i].cap > edges[i].flow)){
					dep[v] = dep[u] + 1;
					Q.push(v);
				}
			}
		} 
		return dep[t];
	}
	int dfs(int u, int flow){
		if(u == t || (!flow)) return flow;
		int ret = 0;
		for(int& i = cur[u]; i; i = edges[i].next){
			int v = edges[i].v, d;
			if((dep[v] == dep[u] + 1) && (d = dfs(v, min(flow - ret, edges[i].cap - edges[i].flow)))){
				ret += d; edges[i].flow += d; edges[i ^ 1].flow -= d;
				if(ret == flow) return flow;
			}
		}
		return ret; 
	}
	void dinic(){
		while(bfs()){
			memcpy(cur, head, sizeof(int) * (n + 1));
			maxflow += dfs(s, INF);
		}
	}
}

一些例题:

this

(有待修缮)

标签:int,cap,flow,网络,dep,edges,小记
From: https://www.cnblogs.com/little-corn/p/18155070

相关文章

  • 电力控制系统设计方案:923-6U CPCI的光纤网络电力控制系统
    6UCPCI的光纤网络电力控制系统 一、设备概述   柔性直流输电系统中用于控制与测量的FS系统,适用于风电和太阳能发电的并网快速数值计算和闭环控制,以及与直流输电系统的换流器有关的特殊控制功能,包括门控单元的信号处理。该控制板的最大响应周期为1us,可以适......
  • 无源RLC电路和阻抗匹配 part2:串并联网络变换+L型匹配
    串并联变换(以RL串联→并联为例)若使上述变换成立,串联支路(Ls、Rs)总阻抗应等于并联支路(Lp、Rp)总阻抗因为可得RC串联→并联:上述变换为窄带阻抗变换,仅在以w0为中心的窄带内成立L型匹配L型匹配所用元件较少,仅用两个无源器件即可构成(电容or电感),根据Rs和Rl的大小关系可分......
  • linux 网络 cat /proc/net/dev 查看测试网络丢包情况
    可以通过cat/proc/net/dev查看测试网络丢包情况,drop关键字,查看所有网卡的丢包情况 bytes:接口发送或接收的数据的总字节数packets:接口发送或接收的数据包总数errs:由设备驱动程序检测到的发送或接收错误的总数drop:设备驱动程序丢弃的数据包总数fifo:FIFO缓冲区错误的......
  • ubuntu debina 设置网络代理
    1.在Ubuntu上:设置>网络>网络代理>手动在Debian上:设置>网络>网络代理>手动2.填充http、https和ftp的代理值。如果您有SOCKS代理,也请进行相应设置。保存更改后,系统将自动选择它们。如果您使用的是Firefox浏览器,则需要在首选项>网络设置>手动代理......
  • 【rust】《Rust深度学习[4]-理解线性网络(Candle)》
    全连接/线性在神经网络中,全连接层,也称为线性层,是一种层,其中来自一层的所有输入都连接到下一层的每个激活单元。在大多数流行的机器学习模型中,网络的最后几层是完全连接的。实际上,这种类型的层执行基于在先前层中学习的特征输出类别预测的任务。全连接层的示例,具有四个输入节点......
  • 【rust】《Rust深度学习[5]-理解卷积神经网络(Candle)》
    卷积神经网络ConvolutionalNeuralNetwork,简称为CNN。CNN与一般的顺传播型神经网络不同,它不仅是由全结合层,还由卷积层(ConvolutionLayer)和池层(PoolingLayer)构成的神经网络。在卷积层和池化层中,如下图所示,缩小输入神经元的一部分区域,局部地与下一层进行对应。每一层都有一个称......
  • FasterViT:英伟达提出分层注意力,构造高吞吐CNN-ViT混合网络 | ICLR 2024
    论文设计了新的CNN-ViT混合神经网络FasterViT,重点关注计算机视觉应用的图像吞吐能力。FasterViT结合CNN的局部特征学习的特性和ViT的全局建模特性,引入分层注意力(HAT)方法在降低计算成本的同时增加窗口间的交互。在包括分类、对象检测和分割各种CV任务上,FasterViT在精度与图像吞吐......
  • Centos8如何重启网络服务
    1.重启网卡之前一定要重新载入一下配置文件,不然不能立即生效nmclicreload2.重启网卡(下面的三条命令都可以):nmclicupens160nmclidreapplyens160nmclidconnectens160备注:ens160是网卡名字 ------------------------------------------------------centos8重启......
  • docker网络
    一:docker网络基础知识1:网络驱动docker网路子系统使用可插拔(理解一下)的驱动,默认的情况下有多个驱动的程序,并且提供核心的联网的功能1、bridge:桥接网络,这个是默认的网络驱动程序,不指定驱动成创建的容器默认是bridge驱动2、host:主机网络,消除了容器和主机网络隔离,直接使用主机的网......
  • Python企业面试题5 —— 网络编程和并发
    1.简述进程、线程和协程的区别以及应用场景?#进程:拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度。#线程:拥有自己独立的栈和共享的堆,线程也由操作系统调度。#协程和线程:协程避免了无意义的调度,由此可以提高性能;但同时协程失去了线程使用多CPU的能力。进程与......