最小割=最大流
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;
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 dfs()//找增广路
{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(dfs())//还有增广路{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;
}