ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)

时间:2023-03-08 22:18:53

  基于残留网络与FF算法的改进-EK算法,核心是将一条边的单向残留容量的减少看做反向残留流量的增加。

//网络流
//EK算法
//Time:16Ms Memory:348K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std; #define MAX 205
#define INF 0x3f3f3f3f int n, m;
int res[MAX][MAX];
int pre[MAX];
bool v[MAX]; bool bfs(int s,int t) //寻找s->t的增广路
{
memset(v, false , sizeof(v));
memset(pre, -1, sizeof(pre));
queue<int> q;
q.push(s);
v[s] = true;
while (!q.empty()) {
int cur = q.front(); q.pop();
for (int i = 1; i <= n; i++)
{
if (!v[i] && res[cur][i])
{
pre[i] = cur;
if (i == t) return true; //找到增广路
q.push(i); v[i] = true;
}
}
}
return false;
} int EK(int s, int t)
{
int maxFlow = 0;
while (bfs(s, t))
{
int mind = INF; //最小可改进量
for (int i = t; i != s; i = pre[i])
mind = min(mind, res[pre[i]][i]);
for (int i = t; i != s; i = pre[i])
{
res[pre[i]][i] -= mind;
res[i][pre[i]] += mind;
}
maxFlow += mind;
}
return maxFlow;
} int main()
{
//freopen("in.txt", "r", stdin); while (~scanf("%d%d", &m, &n))
{
memset(res, 0, sizeof(res));
int u, v, c;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &c);
res[u][v] += c;
} printf("%d\n", EK(1, n));
} return 0;
}