采用ISAP算法,求网络流的最大流
#include <bits/stdc++.h>
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define LL long long
#define ULL unsigned long long
#define EPS 1e-8
using namespace std;
const LL INF = 1e9;
int n, m, s, t;
const int N = 250, M = 11000;
int cnt = 1, head[N];
struct
{
int from, to, next, w;
} e[M];
void add(int u, int v, int w)
{
cnt++;
e[cnt].from = u;
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = head[u];
head[u] = cnt;
}
int now[M], pre[M];
int dep[M], gap[M];
void bfs()
{
memset(gap, 0, sizeof(gap));
memset(dep, 0, sizeof(dep));
dep[t] = 1;
queue<int> Q;
Q.push(t);
while (!Q.empty())
{
int u = Q.front();
Q.pop();
gap[dep[u]]++;
for (int i = head[u]; i > 0; i = e[i].next)
{
int v = e[i].to;
if (e[i ^ 1].w && dep[v] == 0)
{
dep[v] = dep[u] + 1;
Q.push(v);
}
}
}
}
LL Augment()
{
LL v = t, flow = INF;
while (v != s)
{
int u = pre[v];
if (e[u].w < flow)
flow = e[u].w;
v = e[u].from;
}
v = t;
while (v != s)
{
int u = pre[v];
e[u].w -= flow;
e[u ^ 1].w += flow;
v = e[u].from;
}
return flow;
}
void ISAP()
{
bfs();
LL flow = 0;
int u = s;
memcpy(now, head, sizeof(head));
while (dep[s] <= n)
{
if (u == t)
{
flow += Augment();
u = s;
}
bool ok = 0;
for (int i = now[u]; i; i = e[i].next)
{
int v = e[i].to;
if (e[i].w && dep[v] + 1 == dep[u])
{
ok = 1;
pre[v] = i;
now[u] = i;
u = v;
break;
}
}
if (!ok)
{
if (!--gap[dep[u]])
break;
int mindep = n + 10;
for (int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if (dep[v] < mindep && e[i].w)
mindep = dep[v];
}
dep[u] = mindep + 1;
gap[dep[u]]++;
now[u] = head[u];
if (u != s)
u = e[pre[u]].from;
}
}
printf("%lld", flow);
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, 0);
}
ISAP();
return 0;
}