网络流E-K
最小割=最大流
bfs()找增广路(最短路思想)
- 初始化,mf0=0.mf[S]=∞.S入队。
- 只要队不空,u点出队.
- 枚举u的所有出边,更新u的最
小容量,记录前驱边,扩展儿子入队。 - 若能走到T点,返回true。
- 若不能走到T点,返回false。
- 枚举u的所有出边,更新u的最
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;
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18737655

浙公网安备 33010602011771号