Pagini recente » Cod sursa (job #2212499) | Cod sursa (job #583845) | Istoria paginii runda/oji_cls.10 | Cod sursa (job #2044737) | Cod sursa (job #2850943)
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
const int NMAX = 350, INF = 1e9, QSIZE = (1 << 9) - 1;
int flow[NMAX + 1][NMAX + 1], cap[NMAX + 1][NMAX + 1], cst[NMAX + 1][NMAX + 1];
int father[NMAX + 1], minDist[NMAX + 1], q[1 << 9];
bool inQ[NMAX + 1];
vector<int> adj[NMAX + 1];
int bellmanFord(int src, int sink);
int pushFlow(int sink);
int main() {
int n, m, src, sink, i, nd1, nd2, minCst;
FILE *fin = fopen("fmcm.in", "r");
fscanf(fin, "%d%d%d%d", &n, &m, &src, &sink);
for (i = 0; i < m; i++) {
fscanf(fin, "%d%d", &nd1, &nd2);
fscanf(fin, "%d%d", &cap[nd1][nd2], &cst[nd1][nd2]);
cst[nd2][nd1] = -cst[nd1][nd2];
adj[nd1].push_back(nd2);
adj[nd2].push_back(nd1);
}
fclose(fin);
minCst = 0;
while (bellmanFord(src, sink))
minCst += pushFlow(sink);
FILE *fout = fopen("fmcm.out", "w");
fprintf(fout, "%d", minCst);
fclose(fout);
return 0;
}
int bellmanFord(int src, int sink) {
for (int i = 1; i <= NMAX; i++)
minDist[i] = INF, father[i] = 0;
int l = 0, r = 1;
q[0] = src;
inQ[src] = 1;
minDist[src] = 0;
while (l != r) {
int nd = q[l];
l = (l + 1) & QSIZE;
inQ[nd] = 0;
for (auto nxt: adj[nd]) {
if (flow[nd][nxt] != cap[nd][nxt] && minDist[nxt] > minDist[nd] + cst[nd][nxt]) {
minDist[nxt] = minDist[nd] + cst[nd][nxt];
father[nxt] = nd;
if (!inQ[nxt]) {
inQ[nxt] = 1;
q[r] = nxt;
r = (r + 1) & QSIZE;
}
}
}
}
return father[sink];
}
int pushFlow(int sink) {
int nd = sink, minFlow = INF, minCst;
while (father[nd]) {
minFlow = min(minFlow, cap[father[nd]][nd] - flow[father[nd]][nd]);
nd = father[nd];
}
nd = sink;
minCst = 0;
while (father[nd]) {
minCst += cst[father[nd]][nd] * minFlow;
flow[father[nd]][nd] += minFlow;
flow[nd][father[nd]] -= minFlow;
nd = father[nd];
}
return minCst;
}