EK原理
EK算法是求网络流最大流的算法。也称为寻找增广路算法,每次寻找一条增广路,求出这条路上最小的容量(木板原理),然后累加起来,直到最后找不到一条增广路为止。注意,在找到最小容量的时候,前向边要减去最小容量,而后向边要加上最小容量。这是为了形成能改正之前寻找增广路错误的残余网络,实际上这就是把之前的容量退回去,形成新的可行路径。
- Code
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#define MIN(a,b) ((a)>(b)? (b):(a))
using namespace std;
const int SIZE=200;
const int INF=0x3f3f3f3f;
int src,des;
int map[SIZE][SIZE];
int pre[SIZE];
int n;
void build()
{
}
bool bfs(int src,int des)
{
memset(pre,-1,sizeof(pre));
queue<int> que;
que.push(src);
pre[src]=0;
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;i<=1+n;i++)
if(pre[i]==-1&&map[now][i]>0){
pre[i]=now;
if(i==des)
return true;
que.push(i);
}
}
return false;
}
int EK(int src,int des)
{
int maxflow=0;
while(bfs(src,des)){
int minflow=INF;
for(int i=des;i!=src;i=pre[i])
minflow=MIN(minflow,map[pre[i]][i]);
for(int i=des;i!=src;i=pre[i])
map[pre[i]][i]-=minflow,
map[i][pre[i]]+=minflow;
maxflow+=minflow;
}
return maxflow;
}
int main()
{
build();
printf("%d\n",EK(src,des));
return 0;
}