网络流之最大流
Dinic+SPFA
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define N 5010
#define M 50010
int S, T;
int last[N], nxt[M * 2], to[M * 2], ls[M * 2], co[M * 2], len = 1;
int vi[N], dis[N];
int sum = 0, cost = 0;
queue<int> q;
void add(int x, int y, int w, int c) {
to[++len] = y;
nxt[len] = last[x];
ls[len] = w;
co[len] = c;
last[x] = len;
}
int SPFA() {
memset(dis, 127, sizeof(dis));
memset(vi, 0, sizeof(vi));
dis[S] = 0, vi[S] = 1;
q.push(S);
while(!q.empty()) {
int x = q.front();
q.pop();
for(int i = last[x]; i; i = nxt[i]) {
int y = to[i];
if(ls[i] && dis[x] + co[i] < dis[y]) {
dis[y] = dis[x] + co[i];
if(!vi[y]) {
vi[y] = 1;
q.push(y);
}
}
}
vi[x] = 0;
}
return dis[T] < dis[0];
}
int dfs(int k, int flow) {
if(k == T) return flow;
int have = 0;
vi[k] = 1;
for(int i = last[k]; i; i = nxt[i]) {
if(!vi[to[i]] && ls[i] && dis[k] + co[i] == dis[to[i]]) {
int now = dfs(to[i], min(ls[i], flow - have));
ls[i] -= now, ls[i ^ 1] += now, have += now;
cost += now * co[i];
if(have == flow) break;
}
}
vi[k] = 0;
return have;
}
int main() {
int n, m, x, y, w, c, i;
scanf("%d%d%d%d", &n, &m, &S, &T);
for(i = 1; i <= m; i++) {
scanf("%d%d%d%d", &x, &y, &w, &c);
add(x, y, w, c), add(y, x, 0, -c);
}
while(SPFA()) {
while(1) {
int t = dfs(S, 2e9);
if(t) sum += t; else break;
}
}
printf("%d %d\n", sum, cost);
return 0;
}