#include <cstdio>
#include <cstring>
#define Min(_A, _B) (_A < _B ? _A : _B)
#define R register
int F()
{
R int x; R char ch;
while(ch = getchar(), ch < '0' || ch > '9'); x = ch - '0';
while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - '0';
return x;
}
const int MaxN = 410, MaxM = 15010, Inf = 2147483647;
int S, T, pi1, Ans, Sum;
int Point[MaxN], Next[MaxM << 1], To[MaxM << 1], W[MaxM << 1], C[MaxM << 1], q = 1;
void Add(R int u, R int v, R int c, R int w)
{
Next[++q] = Point[u]; Point[u] = q; To[q] = v; C[q] = c; W[q] = w;
Next[++q] = Point[v]; Point[v] = q; To[q] = u; C[q] = 0; W[q] = -w;
}
bool vis[MaxN];
bool modlabel()
{
int d = Inf;
for(int i = 1; i <= T; ++i) if(vis[i])
for(int j = Point[i]; j; j = Next[j])
if(C[j] && !vis[To[j]] && W[j] < d) d = W[j];
if(d == Inf) return 0;
for(int i = 1;i <= T; ++i) if(vis[i])
for(int j = Point[i]; j; j = Next[j])
W[j] -= d, W[j ^ 1] += d;
pi1 += d;
return 1;
}
int agu(R int Now, R int Flow)
{
vis[Now] = 1;
if(Now == T)
{
Ans += Flow * pi1;
return Flow;
}
R int tmp, f = Flow;
for(R int j = Point[Now]; j; j = Next[j])
if(!vis[To[j]] && C[j] && !W[j] && (tmp = agu(To[j], Min(f, C[j]))))
{
C[j] -= tmp;
C[j ^ 1] += tmp;
f -= tmp;
if(f == 0) return Flow;
}
return Flow - f;
}
void zkwMCMF()
{
do
{
R int tmp;
do
{
memset(vis, 0, sizeof(vis));
tmp = agu(S, Inf);
Sum += tmp;
}
while(tmp);
}
while(modlabel());
}
int main()
{
R int n, m;
scanf("%d %d", &n, &m);
for(R int i = 1; i <= m; i++)
{
R int u = F(), v = F(), c = F(), w = F();
Add(u, v, c, w);
}
S = 1, T = n; zkwMCMF();
printf("%d %d\n", Sum, Ans);
}
//https://artofproblemsolving.com/community/c1368h1020435
ZKW费用流模板
最新推荐文章于 2020-08-22 11:21:58 发布