网络流-最小割

割是一种对网络流点的划分方式
对于一个网络流图G(V,E),划分为S和T两部分,其中T=V-S,源点s∈S,汇点t∈T
净流f(S,T)表示穿过割(S,T)的流量之和
f(S,T)=Σf(u,v) | u∈S,v∈T
割的容量C(S,T)为所有从S到T的边容量之和
C(S,T)=Σc(u,v) | u∈S,v∈T
f(S,T)算穿过割(S,T)的正反向边,而C(S,T)只算正向边

最小割指容量最小的可能的割

最大流最小割定理

对于一个网络流图G(V,E),最大流的值等于最小割的容量

增广路

在学习最大流时,可以使用增广路算法来求最大流,但是增广路算法都是在找不到增广路时,就得出了最大流的值。

证明

若残留网络Gf不存在增广路,则Gf中不存在路径从s到达t
定义S集合为:残留网络中s可到达的点
(S,T)构成一个割(S,T)
若f(u,v)小于c(u,v),则Gf(u,v)>0,与上述“不存在路径从s到达t”矛盾
所以f(S,T)=C(S,T)
因为f(S,T)<最小割,又因为f(S,T)=C(S,T)
所以f(S,T)为最大流

求最小割

据“最大流最小割定理”,可使用求最大流的算法求最小割
这里使用dinic算法求最小割

部分代码

void bfs()
{
	memset(h,-1,sizeof(h));
	q[1]=1;
	h[1]=0;
	int qh=1,qt=1;
	while (qh<=qt)
	 {
	 	for (int i=linkk[q[qh]];i;i=e[i].next)
	 	 if (h[e[i].y]==-1 && e[i].v)
	 	  {
	 	  	h[e[i].y]=h[q[qh]]+1;
	 	  	q[++qt]=e[i].y;
	 	  }
	 	qh++;
	 }
	if (h[n]!=-1) flag=true;
}

int dfs(int k,int delta)
{
	if (k==n) return delta;
	int ma=0;
	for (int i=linkk[k];i && ma<delta;i=e[i].next)
	 if (h[e[i].y]==h[k]+1 && e[i].v)
	  {
	  	if (add=dfs(e[i].y,min(e[i].v,delta-ma)))
	  	 {
	  	 	ma+=add;
	  	 	e[i].v-=add;
	  	 	e[i^1].v+=add;
	  	 }
	  }
	if (!ma) h[k]=-1;
	return ma;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值