EK算法的思路非常的简单,就是一直找增广路径(BFS),假如有,记录增广路的最小值k,ans +=k ,并更新网络的值(要用反向边)。
贴模板:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define N 10005
#define M 200005
#define inf 0x3f3f3f3f
using namespace std;
int n,m,s,t,cnt=1,head[N],incf[N],pre[N],maxflow;
bool vis[N];
struct Node{
int to,nxt,val;
}edge[M];
void add(int x,int y,int z)
{
cnt++;
edge[cnt].to=y;
edge[cnt].nxt=head[x];
edge[cnt].val=z;
head[x]=cnt;
}
bool bfs()//寻找增光路
{
memset(vis,0,sizeof vis);
queue<int> q;
q.push(s); vis[s]=1; incf[s]=inf;
while(q.size())
{
int u=q.front(); q.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
if(edge[i].val)
{
int v=edge[i].to;
if(vis[v]) continue;
incf[v]=min(incf[u],edge[i].val);
pre[v]=i; //记录前驱,便于找到最长路的实际方案
q.push(v); vis[v]=1;
if(v==t) return true;
}
}
}
return false;
}
void update()//正向边-流,反向边+流
{
int x=t;
while(x!=s)
{
int i=pre[x];
edge[i].val-=incf[t];
edge[i^1].val+=incf[t];
x=edge[i^1].to;
}
maxflow+=incf[t];
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,0);//成对储存
}
while(bfs()) update();
printf("%d",maxflow);
return 0;
}