最大流EK算法模板

时间:2023-03-09 16:40:59
最大流EK算法模板

  最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用。

  

 #include<cstdio>
#include<cstring>
using namespace std; #define _clr(x, y) memset(x, y, sizeof (x))
#define Min(x, y) (x < y ? x : y)
#define INF 0x3f3f3f3f
#define N 210 int map[N][N];
int pre[N], Sta[N];
bool used[N];
int n, m; //bfs判断s--t之间是否还存在增广路
bool bfs(int s, int t)
{
_clr(used, );
_clr(pre, -);
int top=;
Sta[top++] = s;
used[s] = true;
while(top)
{
int v = Sta[--top];
for(int i=; i<=n; i++)
{
if(map[v][i] && !used[i])
{
used[i] = true;
pre[i] = v;
if(i==t)
return true;
Sta[top++] = i;
}
}
}
return false;
} int EK(int s, int t)
{
//初始化最大流为0
int maxFlow=, d; //若s--t之间存在增广路
while(bfs(s, t))
{
d = INF;
//找到最小的可增量
for(int i=t; i!=s; i=pre[i])
d = Min(d, map[pre[i]][i]); //添加反向边,更新残留网络
for(int i=t; i!=s; i=pre[i])
{
map[pre[i]][i] -= d;
map[i][pre[i]] += d;
}
maxFlow += d;
}
return maxFlow;
} int main()
{
int x, y, z;
while(~scanf("%d%d", &m, &n))
{
_clr(map, );
for(int i=; i<m; i++)
{
scanf("%d%d%d",&x, &y, &z);
map[x][y] += z;
}
printf("%d\n",EK(, n));
}
return ;
}

Fulkersion_ford算法和Ekaf算法基本 是一样的,不同之处在与u搜索增广路时,一个用队列保存,一个用栈保存;

 #include <cstdio>
#include <cstring>
#include <queue>
#define _clr(x, y) memset(x, y, sizeof(x))
#define Min(x, y) (x < y ? x : y)
#define INF 0x3f3f3f3f
#define N 110
#define M 1005
using namespace std; int edge[N][N], n;
int pre[N], rec[N];
int alpha[N], Sta[N];
int S, T; void Ford_Fulkerson()
{
int maxf=;
while()
{
int top=;
_clr(pre, -);
_clr(alpha, );
pre[S] = S;
alpha[S] = INF;
Sta[top++] = S;
while(top)
{
int u = Sta[--top];
for(int i=; i<=T; i++)
{
if(edge[u][i]> && pre[i]==-)
{
pre[i] = u;
alpha[i] = Min(alpha[u], edge[u][i]);
Sta[top++] = i;
}
}
if(alpha[T]) break;
}
if(alpha[T]==) break; maxf += alpha[T];
for(int i=T; i!=S; i=pre[i])
{
edge[pre[i]][i] -= alpha[T];
edge[i][pre[i]] += alpha[T];
}
}
printf("%d\n", maxf);
} int main()
{
int m, num, k;
while(~scanf("%d%d", &m, &n))
{
int pig[M], last[M];
S=, T=n+;
_clr(edge, );
_clr(last, );
for(int i=; i<=m; i++) scanf("%d", pig+i);
for(int i=; i<=n; i++)
{
scanf("%d", &num);
while(num--)
{
scanf("%d", &k);
if(last[k]==)
edge[S][i] += pig[k];
else
edge[last[k]][i] = INF;
last[k] = i;
}
scanf("%d", &edge[i][T]);
}
Ford_Fulkerson();
}
return ;
}