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

网络流笔记

时间:2023-10-12 15:56:41浏览次数:40  
标签:return int 复杂度 网络 rest 笔记 Dinic now

前言

粗略地讲一下吧,大概能理解就行

理论部分借鉴了 oi-wiki ,有问题欢迎指出

网络流

网络是一个特殊有向图 $G=(V,E)$ ,特殊在于有源点 $s$ 和汇点 $t$

首先网络流图中每条边 $(u,v)$ 都有一个容量 $c(u,v)$

介绍流函数 $f(u,v)$ ,指 $u$ 到 $v$ 流量

所以就会有流量守恒,即 $0 \leq f(u,v) \leq c(u,v)$

然后一个点的净流量是指 $u$ 向其它点的流量减去其它点向它的流量

所以有净流量 $f(u)=\sum_{x\in V} f(u,x) - \sum_{x\in V} f(x,u) $

而图 $G$ 的流量就是 $|f(s)|$

最大流

就是求 $|f(s)|$ 的最大值

思路和二分图很像,就是一直找 $s$ 到 $t$ 的增广路

直到不存在增广路为止,于是就诞生了 EK(Edmond-Karp) 算法

复杂度证明比较复杂,就不讨论了,复杂度是 $O(n m^2)$ ,但跑不满, $1000$ 的数据跑着也比较轻松(

但这里主要介绍代码长度与 EK 差不多 ,复杂度更为优秀的 Dinic 算法

Dinic算法

发现 EK 可能会把很多拓展过后的点或边再拓展

我们在每次有效增广过后删除增广的边

并且用 $bfs$ 先建立分层图,保证沿着搜索顺序扩张

复杂度 $O(n^2m)$

代码:

template<int T> struct Dinic{
	struct edge{
		int v,w,next;
	}e[T*5+5];
	int head[T+5],tot,now[T+5],d[T+5];
	Dinic(){
		tot=1;
		for(int i=1;i<=T;i++) head[i]=0;
	}
	inline void add(int x,int y,int c){
		e[++tot]={y,c,head[x]};
		head[x]=tot;
		e[++tot]={x,0,head[y]};
		head[y]=tot;
	}
	int inf=2e9;
	inline int bfs(int s,int t){
		for(int i=1;i<=T;i++) d[i]=0;
		queue<int> q;
		while(q.size()) q.pop();
		d[s]=1; q.push(s); now[s]=head[s];
		while(q.size()){
			int u=q.front();
			q.pop();
			for(int i=now[u];i;i=e[i].next){
				int v=e[i].v;
				if(e[i].w&&d[v]==0){
					d[v]=d[u]+1;
					now[v]=head[v];
					q.push(v);
					if(v==t) return 1;
				}
			}
		}
		return 0;
	}
	int dinic(int u,int flow,int t){
		if(u==t) return flow;
		int rest=flow,ret=0;
		for(int i=now[u];i&&rest;i=e[i].next){
			int v=e[i].v;
			now[u]=i;
			if(e[i].w&&(d[v]==d[u]+1)){
				int p=dinic(v,min(rest,e[i].w),t);
				if(!p){
					d[v]=0;
					continue;
				}
				rest-=p;
				ret+=p;
				e[i].w-=p;
				e[i^1].w+=p;
			}
		}
		return ret;
	}
	inline int flow(int s,int t){
		for(int i=1;i<=T;i++) now[i]=0;
		int ret=0,w;
		while(bfs(s,t)) {
			while(1){
				w=dinic(s,inf,t);
				ret+=w;
				if(!w) break;
			}
		}
		return ret;
	}
};

实现用的链式前向星建图,比较方便。

标签:return,int,复杂度,网络,rest,笔记,Dinic,now
From: https://www.cnblogs.com/yzq-yzq/p/17759686.html

相关文章

  • 《信息安全系统设计与实现》第六周学习笔记
    一、课程内容第十一章学习EXT2文件数据结构1、通过mkfs创建虚拟磁盘mke2fs[-bblksize-Nninodes]devicenblocks虚拟磁盘布局:2、操作系统内核中的文件系统函数3、系统调用4、I/O库函数5、用户命令6、sh脚本低级别的文件操作中的常用函数:打开和关闭文件:open():打......
  • DR7808 配置笔记
    CSA部分:内部CSA可以配置为单向,或者双向,一共有两个CSA,内部CSA的GAIN可以配置,挡位有10,20,40,80四种增益选项。也可以直接关闭内部CSA,CSA的过流保护值和过流保护滤波时间都可以单独设置。相关寄存器:DR7808_GENCTRL1DR7808_HBIDIAGDR7808_GENCTRL2DR7808_CSA_OC_SH寄存器相关描......
  • C#学习笔记--面向对象三大特征
    C#核心面向对象--封装用程序来抽象现实世界,(万物皆对象)来编程实现功能。三大特性:封装、继承、多态。类与对象声明位置:namespace中样式:class类名{}命名:帕斯卡命名法(首字母大写)实例化对象:根据类来新建一个对象。Personp=newPerson();成员变量声明在类语句块中用来描述......
  • 【刷题笔记】80. Remove Duplicates from Sorted Array II
    题目Givenasortedarraynums,removetheduplicatesin-placesuchthatduplicatesappearedatmosttwiceandreturnthenewlength.Donotallocateextraspaceforanotherarray,youmustdothisbymodifyingtheinputarrayin-placewithO(1)extramemor......
  • 开发者笔记 C++11新特性并发编程future
    上一篇介绍了<thread>文件里线程相关类,这篇将介绍C++<future>头文件里线程类,future里包含的类主要是处理异步任务,线程函数封装,线程间通信,同步,捕捉异常处理https://zhuanlan.zhihu.com/p/509118687future的引入c++11引入的future是为了解决异步通信问题的。future可以看做是数......
  • 《动手学深度学习 Pytorch版》 8.6 循环神经网络的简洁实现
    importtorchfromtorchimportnnfromtorch.nnimportfunctionalasFfromd2limporttorchasd2lbatch_size,num_steps=32,35train_iter,vocab=d2l.load_data_time_machine(batch_size,num_steps)8.6.1定义模型num_hiddens=256rnn_layer=nn.RNN(len(......
  • 2023_10_12_MYSQL_DAY_04_笔记
    2023_10_12_MYSQL_DAY_04_笔记14章课后作业CREATETABLExi(xidINTPRIMARYKEYAUTO_INCREMENT,xnameVARCHAR(10)UNIQUE,xheadVARCHAR(10)NOTNULL,xlocVARCHAR(30)DEFAULT'浑南区');CREATETABLEclass02(cnoINTPRIMARYKEY......
  • destoon开发笔记-调取资讯标题图
    今天也没做什么,就帮一个朋友调试了DT内核开发的模板,调取资讯内容第一张图作为标题图,网上也有一些教程,感觉不太好,所以我就写详细一些,希望对大家有帮助! 第一步:修改module\article\admin\template\edit.tpl.php     1<inputname="post[thumb_no]" type="te......
  • python 基础笔记-函数
    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段·。   好处为: 一可以把程序中相对独立的功能模块抽取出来,减少重读代码的编写; 二是将来可以以重复的使用这些功能模块https://www.clw9335.com/zx/index-htm-page-5.html  定义一个函数 你可以定义一......
  • Qt信号槽与事件循环学习笔记
    事件与事件循环信号槽机制事件与事件循环在Qt中,事件(event)被封装为QEvent类/子类对象,用来表示应用内部或外部发生的各种事情。事件可以被任何QObject子类的对象接收并处理。根据事件的创建方式和调度方式,Qt中事件可分为三类,分别是:自发事件(Spontaneousevent)由窗口系统(windo......