关于ISAP:https://www.cnblogs.com/owenyu/p/6852664.html
同时也是poj1273 / codevs1993的题解
USACO的奶牛题,网络流模板
这道题codevs上的数据很水...
还要注意poj上是多组数据
//poj1273 / codevs1993
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5000 + 5;
const int INF = 0x3f3f3f3f;
int ecnt, from[MAXN * 2], to[MAXN * 2], nxt[MAXN * 2], cap[MAXN * 2];
int fst[MAXN], cur[MAXN], p[MAXN]; //graph
int n, m;
inline void add(int u, int v, int c) {
ecnt++;
from[ecnt] = u;
to[ecnt] = v;
cap[ecnt] = c;
nxt[ecnt] = fst[u];
fst[u] = ecnt;
}
bool vis[MAXN];
int d[MAXN];
bool bfs(int s, int t) {
//逆向BFS O(n+m)
memset(vis, 0, sizeof(vis));
queue<int> q;
q.push(t);
d[t] = 0;
vis[t] = true;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = fst[u]; i; i = nxt[i]) {
int v = to[i];
if (!vis[v]) {
vis[v] = true;
d[v] = d[u] + 1;
q.push(v);
}
}
}
return vis[s];
}
int Augment(int s, int t) {
int u = t, a = INF;
for (; u != s; u = from[p[u]]) {
a = min(a, cap[p[u]]);
}
for (u = t; u != s; u = from[p[u]]) {
cap[p[u]] -= a;
cap[p[u] ^ 1] += a;
}
return a;
}
int gap[MAXN];
int ISAP(int s, int t) {
bfs(s, t);
memset(gap, 0, sizeof(gap));
for (int i = 1; i <= n; i++)gap[d[i]]++;
memcpy(cur, fst, sizeof(fst));//for (int i = 1; i <= n; i++)cur[i] = fst[i];
int u = s, flow = 0;
while (d[s] < n) {
if (u == t) {
flow += Augment(s, t);
u = s;
}
bool ok = false;
for (int i = cur[u]; i; i = nxt[i]) {
int v = to[i];
if (cap[i] > 0 && d[u] == d[v] + 1) {
ok = true;
p[v] = i;
cur[u] = i; //Caution!
u = v;
break;
}
}
if (!ok) { //Retreat
int m = n - 1; //Caution
for (int i = fst[u]; i; i = nxt[i]) {
if (cap[i] > 0) {
m = min(m, d[to[i]]);
}
}
if (--gap[d[u]] == 0)break;
d[u] = m + 1;
gap[d[u]]++;
cur[u] = fst[u];
if (u != s)u = from[p[u]];
}
}
return flow;
}
int main() {
while (scanf("%d%d", &m, &n) == 2) {
memset(fst, 0, sizeof(fst));
ecnt = 1;
while (m--) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add(u, v, c);
add(v, u, 0);
}
int ans = ISAP(1, n);
printf("%d\n", ans);
}
return 0;
}