首页 > 其他分享 >最大流

最大流

时间:2024-02-04 12:56:46浏览次数:23  
标签:二分 tmp 最大 增广 int level dinic

最大流问题

有向图 G 中,有两个特殊的点,源点和汇点,每条边有指定的容量,求S到T的最大流。

就像从源点放水,水量无穷大,汇点的水量是多少?

定义

c为容量,f为流量

流量守恒

\(f(x,y)\leq c(x,y)\)

容量性质

\(\sum f(u,x) = \sum f(x,u)\)

斜对称性

\(f(x,y) = -f(y,x)\)

容量网络,流量网络

残留网络=容量网络-流量网络,连两条边

增广路:残留网络上从源点到汇点的简单路径

反向弧:给算法“返悔的机会”

增广路定理:当前流为最大流的充要条件是无增广路

Ford-Fulkerson 方法

Edmonds-Karp 算法

残留流量为正,BFS

\(O(VE^2)\)

Dinic 算法

分层网络,用DFS一次求解多个增广路

BFS分层,DFS多路增广,当前弧优化:一个点被dfs两次,而接上去的前几个点无法增广,所以记录当前弧

正常时 \(O(V^2E)\)

二分图时 \(O(\sqrt{V}E)\)

实现

斜对称修改

u->v的边要记录v->u的边的下标。

链式前向星只需要把下标换成从2开始,异或1 tot=1

int dinic(){
	int res=0;
	while(dinic_bfs())res+=dinic_dfs(S,INF);
	return res;
}
bool dinic_bfs(){
	for(int i=1;i<=T;++i)h[i]=oh[i],level[i]=0;
	queue<int> q;
	q.push(S);
	level[S] = 1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=h[x];i;i=e[i].ne){
			int y=e[i].to;
			if(!level[y]&&e[i].c>e[i].f){
				level[y] = level[x]+1;
				q.push(y);
			}
		} 
	}
	return level[T]!=0;
}
int dinic_dfs(int x,int cp){
	if(x==T)return cp;
	int tmp=cp;
	for(int &i=h[x];i;i=e[i].ne){//邻接表
		int y=e[i].to;
		if(level[y]==level[x]+1&&e[i].c>e[i].f){
			int t=dinic_dfs(y,min(tmp,e[i].c-e[i].f));//记住流量要实时减少tmp而非cp
			e[i].f += t;e[i^1].f -= t;
			tmp -= t;
			if(tmp==0)break;//当前弧更换要注意可能是tmp不够了而不是无法增广,所以不能放在for的条件判断上
		}
	}
	return cp-tmp;
}

实际应用(建模)

常用构图方式

S->T流对应原题中的方案

拆点

餐厅一题:拆点

状态表示优化

猪圈问题:一轮建m+1个点,顾客和m个猪圈,跑最大流

优化:一个好几轮没打开的猪圈,出边入边相同,可以合并

多个人使用同一个猪圈,则在他们顾客之间连无穷大的边,省去猪圈的点,和很多很多边,然后从顾客连出去边,符合题意中“特定数量”

行列建点

打扫卫生:行列建点

转化为二分图最小顶点覆盖

马:坏的格子不用连,二分图最大独立集

流网络 割 \((S,T)\) 分成 \(S\) 和 \(T=V-S\) 两个部分

割的容量不算反方向,净流量算反方向

最大流等于最小割定理

二分图性质

二分图匹配,选边,两两间没有公共点(匹配)

二分图最小顶点覆盖,选点,每条边至少有一个端点被选出(覆盖集)

二分图最大独立集,选点,点两两间没有边相连(独立集)

  1. 因为网络流的模型相同,根据最大流最小割定理,二分图最小点覆盖等于最大匹配。

  2. 二分图最大独立集等于总点数减去最小覆盖集。

通过反证,先证充分性,去掉独立集如果不是覆盖集,那么独立集间有边相连,矛盾。再证必要性,覆盖集一定占据了任意一条边的一个端点,那么独立集一定没有相连的边。(充分必要逻辑有问题)

最大权闭合子图问题

一些项目做了会赚钱,一些员工雇佣要花钱。一个项目需要指定的员工,一个员工雇佣后可以参加任意多项目,问经过项目取舍,最多可以挣多少钱?

可以建模成图,一个点选了,则出边都要选。建立网络流模型,原点向项目连边,员工向汇点连边,中间边权无穷大。应当在图上求最小割。

如果 \(S->P\) 没有被割且 \(P->Q->T\) 没有被割,则选了项目没有选人,不合法,而建模与题意吻合,跑最小割。

建模总结

数学研究性质,信息解决问题。

数学善于建立定理,概念。理念和建模是两码事,要符合实际问题。

标签:二分,tmp,最大,增广,int,level,dinic
From: https://www.cnblogs.com/life-of-a-libertine/p/18005977

相关文章

  • 最大子段和
    这道题目跟“生日礼物”非常像,但这里必须刚好选择\(m\)个,为了没有歧义,我们认为两个不同子段一定不会挨着(就是中间必须有数)这个状态具体一下:一定要选择第\(j\)个数但其实我觉得这个方程是有一点问题的,\(k\)应该从\(j-2\)开始减接下来考虑优化空间在考虑优化时间然后这道题......
  • 作为国产深度学习框架中分布式计算特性最强大的OneFlow的最大缺点是什么?
    OneFlow是国产深度学习框架中分布式计算特性最强大的,因为其原生支持分布式特性,世界上的历史中的深度学习框架唯一可以做到这一点的也就只有Google的TensorFlow和Jax了,虽然有人说Google的分布式最强也有人说Google的分布式一般,但是毋庸置疑的是OneFlow一定是国产深度学习框架中分布......
  • 费用流求解二分图最大权匹配
    二分图最大权匹配问题:有\(n_1\)个左部点,\(n_2\)个右部点,\(m\)条边,边有边权\(w_i\),表示若选择这条边就会获得\(w_i\)的收益,求获得收益最大的一种图的匹配方案。若考虑用费用流求解,建立超级源点\(S\)和超级汇点\(T\),\(S\)向每个左部点连边,流量1费用0;每个右部点向\(......
  • 求最大数字-od-python
    求最大数字题目给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533请返回经过删除操作......
  • 数论-最大公因子及其性质
    原文如果a和b为不全为零的整数,则它们的公因子的集合是一个有限的整数集,通常包括+1和-1,我们对其中最大的那个公因子感兴趣.定义2 不全为零的整数a和b的最大公因子是指能够同时整除a和b的最大整数。a和b的最大公因子记作(a,b),(有时也记作gcd(a,b),特别是在非数论的著作中我们将......
  • 现货黄金交易:如何利用杠杆,最大化投资回报?
    黄金一直以来都是投资者们青睐的避险资产,而现货黄金交易则是让投资者有机会参与到黄金市场波动中获取收益的方式之一。而在现货黄金交易中,利用杠杆可以帮助投资者在有限的资本下最大化投资回报。首先,了解杠杆交易的基本概念是至关重要的。杠杆交易是指借用资金来进行投资,以提高投......
  • leetcode85. 最大矩形
    85.最大矩形-力扣(LeetCode)参考dp求最大字串和的思想,将一维dp转化为二维的形式,将当前列的和当成一维的数进行dp即可。这题和求最大子矩阵和的dp思路一样。1classSolution{2public:3intmaximalRectangle(vector<vector<char>>&matrix){4intn=m......
  • SQL PARTITION BY 语句把一张表分组后的最大值或最小值插入另一张表里
    1.例子见前一章,目的是有分组的,只显示OrderAmount最高的(即每组只显示一列) 2.再建一个表来存储CREATETABLE[dbo].[MaxOrders]([orderid][int]NULL,[Orderdate][date]NULL,[CustomerName][varchar](100)NULL,[Customercity][varchar](100)NULL,......
  • 上下界 可行/最大/最小 网络流/费用流(有/无源汇)
    对网络的定义进行扩展,我们可以得出一堆奇奇怪怪的网络。上下界令\(Max_e\)为边\(e\)的流量上界,\(Min_e\)为边\(e\)的流量下界,一条边的流量\(f_e\)要满足\(Min_e\lef_e\leMax_e\),除此之外和普通网络流定义相同,可以发现,普通的网络就是下界为\(0\)的网络。无源汇......
  • Linux中 awk命令输出一列多个类别中 每个类别中最大的项
     001、(base)[b20223040323@admin1test]$lsa.txt(base)[b20223040323@admin1test]$cata.txt##测试数据a88a76b88c10b777c200a87c150a34b25a66##输出第一列中每一类别中值最大的项(base)[b20223040......