EK算法求最大流:
BFS找增广路增广直到无法增广
复杂度:O(V*E^2)
核心代码(邻接表存图):(一开始学最大流的时候写的代码,非常丑)
int pre[maxn];
int vis[maxn]={0};
bool bfs(){//bfs求路径
for(int i = 0;i <= n+1;++i) vis[i] = 0;
queue<int> q;q.push(0);vis[0] = 1;
while(q.size()){
int u = q.front();q.pop();
for(int i = head[u];i!=-1;i = e[i].nxt){
int v = e[i].v;
if(vis[v]) continue;
if(e[i].f == 0) continue;
vis[v] = 1;
pre[v] = i;
q.push(v);
}
}
return vis[n+1];
}
while(bfs()){//更新正向边和反向边的流量
ll d = inf;
int u,v;
v = n+1;
while(v!=0){
u = e[pre[v]].u;
d = min(d,e[pre[v]].f);
v = u;
}
v = n+1;
while(v != 0){
u = e[pre[v]].u;
if(pre[v]&1) mp[u][v]-=d;
else mp[u][v]+=d;
e[pre[v]].f -= d;
e[pre[v]^1].f += d;//给反向边加上回流
v = u;
}
ans += d;
}
Dinic算法求最大流:
先用BFS求图的层次,然后DFS根据BFS求得的深度增广(只走深度比当前结点大1的点)
复杂度:O(V^2 * E)
核心代码:
int dep[maxn];
int q[maxn*2];
int tot,tail;
bool bfs(){
memset(dep,-1,(ex+1)<<2);
dep[st] = 1;
q[tot = 0] = st,tail = 1;
while(tot < tail){
int u = q[tot++];
if(u == ed) break;
for(int i = head[u];~i;i = e[i].nxt){
int v = e[i].v;
if(dep[v]!=-1 || !e[i].f) continue;
dep[v] =