Pagini recente » Cod sursa (job #1611594) | Cod sursa (job #1827489) | Cod sursa (job #2917126) | Cod sursa (job #2744014) | Cod sursa (job #2838292)
#include <iostream>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;
struct MCMF {
const long long INFLL = (long long) 1e18;
const int INFINT = (int) 1e9;
int n, s, d;
struct Edge {
int from, to, cap, cost;
};
vector<Edge> edges;
vector<int> deg;
vector<int> verts;
vector<int> parrent;
vector<long long> mincost;
vector<vector<int>> g;
MCMF(int n, int s, int d) : n(n), s(s), d(d), deg(n, 0), g(n), mincost(n), parrent(n) {
}
void add(int a, int b, int cap, int cost) {
edges.push_back({ a, b, cap, cost });
edges.push_back({ b, a, 0, -cost });
verts.push_back(a);
verts.push_back(b);
deg[a]++;
deg[b]++;
}
pair<long long, long long> get() {
for (int i = 0; i < n; i++)g[i].reserve(deg[i]);
for (int i = 0; i < (int)verts.size(); i++)g[verts[i]].push_back(i);
long long flow = 0, bestcostforflow = 0;
while (1) {
queue<int> q;
for (int i = 0; i < n; i++) mincost[i] = INFLL;
q.push(s);
mincost[s] = 0;
while (!q.empty()) {
int a = q.front();
q.pop();
for (auto& i : g[a]) {
if (edges[i].cap) {
int b = edges[i].to;
long long value_b = mincost[a] + edges[i].cost;
if (value_b < mincost[b]) {
mincost[b] = value_b;
q.push(b);
parrent[b] = i;
}
}
}
}
if (mincost[d] == INFLL)break;
int mn = INFINT;
long long sumcost = 0;
vector<int> path;
for (int i = d; i != s; i = edges[(parrent[i] ^ 1)].to) {
path.push_back(parrent[i]);
mn = min(mn, edges[parrent[i]].cap);
sumcost += edges[parrent[i]].cost;
}
for (auto& i : path) {
edges[i].cap -= mn;
edges[i ^ 1].cap += mn;
}
flow += mn;
bestcostforflow += (long long) mn * sumcost;
}
return { flow, bestcostforflow };
}
};
int main() {
freopen ("fmcm.in", "r", stdin);
freopen ("fmcm.out", "w", stdout);
int n, m, s, d;
cin >> n >> m >> s >> d;
s--;
d--;
MCMF flow(n, s, d);
while (m--) {
int x, y, a, b;
cin >> x >> y >> a >> b;
x--;
y--;
flow.add(x, y, a, b);
}
auto it = flow.get();
cout << it.second << "\n";
}