网络流E-K

最小割=最大流
bfs()找增广路(最短路思想)

  1. 初始化,mf0=0.mf[S]=∞.S入队。
  2. 只要队不空,u点出队.
    • 枚举u的所有出边,更新u的最
      小容量,记录前驱边,扩展儿子入队。
    • 若能走到T点,返回true。
    • 若不能走到T点,返回false。

EK()求最大流(类似挤牙膏)
循环找增广路,每找到一条,

  • 逆序更新残留网,容量“此消彼长”。
  • 累加可行流,最后返回最大流。

板子

#include<bits/stdc++.h>
using namespace std;
const int N=1e4;
int head[N],to[N],w[N],nxt[N];
int tot=1;
void add(int a,int b,int c)
{
	nxt[++tot]=head[a],head[a]=tot,w[tot]=c,to[tot]=b;
	swap(a,b),c=0;
	nxt[++tot]=head[a],head[a]=tot,w[tot]=c,to[tot]=b;
}
int mf[N],pre[N];//S-v 流量上限,前驱
int S,T;//源点,汇点
bool bfs()//找增广路
{
	memset(mf,0,sizeof(mf));
	queue<int > q;
	q.push(S);
	mf[S]=1e9;
	while(q.size())
	{
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=nxt[i])
		{
			int v=to[i];
			if(!mf[v]&&w[i])
			{
				mf[v]=min(mf[u],w[i]);
				pre[v]=i;//记录前驱
				q.push(v);
				if(v==T)//找到一条就返回
					return 1;
			}
		}
	}
	return 0;
}
long long E_K()
{
	long long flow=0;//记录最大流
	while(bfs())//还有增广路
	{
		int v=T;//逆向走
		while(v!=S)
		{
			int i=pre[v];//i是v的前驱
			w[i]-=mf[T];
			w[i^1]+=mf[T];
			v=to[i^1];
		}
		flow+=mf[T];
	}
	return flow;
}
int main()
{

	return 0;
}
posted @ 2025-02-26 08:18  流氓兔LMT  阅读(24)  评论(0)    收藏  举报